The Hard Parts of UI Development

Separating Data & View Updates

Will Sentance

Will Sentance

The Hard Parts of UI Development

Check out a free preview of the full The Hard Parts of UI Development course

The "Separating Data & View Updates" Lesson is part of the full, The Hard Parts of UI Development course featured in this preview video. Here's what you'd learn in this lesson:

Will explains the benefit of decoupling data changes and view updates. Isolating view updates to a single function reduces duplication and makes the code more maintainable. As changes in data occur, the dataToView function will be called.


Transcript from the "Separating Data & View Updates" Lesson

>> I guess let's not forget webcore
>> [LAUGH]
>> Gives JavaScript access to the DOM and pixels still. But this is gonna allow us, what have we changed here? There's our data, one piece of data. There's our handlers, handle click and handle input. Honestly, I'm already feeling better after my pen debacle because when I see this actually it does make me really happy.

Look at that, one function line for dataToview that can affect our view. By the way note, everything is being affected there based on data. We go into the land of ternaries particularly because they are a great way to shorthand, set conditional logic for if data looks this way display this.

And if we're saying that everything that user sees must depend on underlying data. You're gonna imagine we're gonna write a lot of conditionals if data looks this way, display this. If data looks this way, display this. But, it's all in one place and then whatever the user does I'm not gonna have to sort of track back through which actions they took.

All the user can do, when they click or start writing is in line 11 and line 15 you can see it, update the data. And then run that dataToview converter function, one place, one function in which what the user sees can change. What the user or our handlers can do is update data.

It's a restriction that is immensely popular that limits us to only changing underlying data. And then running in this case a single function dataToview that's gonna convert that data into what the user sees. Such that we have, if you wanted to get fancy about it set up some data and then a description of the view based on that data.

And that description is defined as described within the dataToview function. And then whatever the user does must channel through a change of data. Is it perfect, is it the only way to do it? Not at all. Is it an incredibly restrictive and predictable way that ensures that I have a full history?

I can view this as I have this bug. I click this thing, I did this I don't know why this showed up. And we as engineers are going well, it's any one of the 500 lines determine our view. And it's any particular order of the handlers executing that determine what you're seeing?

No. In fact, we'll be able to see if we were to have some sort of debugger tracking the underlying data in our app as the users live running it. We will be able to see exactly the history or we could archive data. You can see exactly the history of our data check data.

And then from that exactly know what the user should and would see. Because the only way to change what the or the only way to display for the user to see anything is via a call to the dataToview function. This could even here, create some interesting situations where whatever the user does we're no longer having to reason about which bit or the view to update.

We're no longer having to go, okay, do you remember here right before? We had to go, okay, if a user starts writing then change the text content of the div, okay? In line handleclick if the user starts right, click, sorry change the value of the input from what's on your mind to empty string.

If the user's not yet done anything, then set the input's value to what's on your mind. And I guess, honestly, have the div have nothing in it. We didn't even state that with a div and said you got nothing in it. Not setting it's still a decision not putting any content in the div is still a decision in implicit one here but still a decision.

No longer do we have to think about four or five different places that we could change under different conditions what the user's done. Instead, just use this action update data. This is a shift in reasoning, though, a shift in way of thinking. It means that every single thing that a user sees, you need to be able to capture it in some way in data.

But you know what you always were. Even though you didn't show that the div had content here, you were implicitly before the user clicked or whatever you were implicitly setting content off. I guess the div was not set it was sort of set to undefined or set to empty string.

There's no such thing as any data anything that's changed on the screen has to have associated data behind it otherwise how you're changing it. So, all we're doing really here is acknowledging that we're saying that everything on the screen must be a so if you want to change it.

Otherwise, fine if you just want to have it no change it to it. But anything be changed must have associated underlying data with it. Don't bring that data at random in a handler and then forget about it or come back to it and or cheat. No, every piece of data will be defined and then at any given set of the data combination you can see exactly what we produced via a single pipeline function called dataToreview.

That will produce the output conditional on that data, not conditional on previous changes to the out previous displays. And then implicitly, there's underlying data that you are changing there without realizing it. No change the data and associated view must change then they can't not be in sync. We're going to see this makes things really quite fun and the way we implement this is not very efficient.

But this if you look at every time we want to change what the user sees which is interaction, right? We are going to run dataToview. What if we just had dataToview run like so often that whenever the user's data changes the view updatable run? And that's exactly what we're going to do right after.

While we would not use this in practice in the long term, it's completely untenable. It's already my favorite word, running dataToview every 15 milliseconds. But that's fast and I can see to ensure any data change as soon as it happens would be displayed. Another funny consequence of doing this model and again this is a move not a truth.

Another funny consequence of this is that there's gonna be nothing on our C++ object that is not at least not for a more than a millisecond or so or 15 milliseconds, I guess. That is not a consequence of our data. Even things, by the way, that we didn't need to update.

When Ian wrote Ian into the field, into the input field we didn't need to then re update Ian. But I don't want to have to reason about, whether to update Ian in this particular situation. I want to keep it everything on that screen must depend on exactly what is in JavaScript data.

Meaning if we look at our little code here, we're going to update input value to whatever the user typed in. In this case Ian, every single time. So when the user starts writing, we're going to update the data in line 15 handleInput. Put inputs value into post and then we're going to redisplay it on the screen because I don't want to work out.

In this condition I only need to update because I want to tell you to do on the click all I actually need to update is the input value to remove the default text. On the typing, all I actually need to update is the div but that's all ready a lot of thinking.

You've got a thousand elements and I've got to work out which ones I need to update on each handler. And it depends on the history of the order of the running of the handlers. I don't know how we got away so long without having this sort of restriction.

So instead, even though it's completely unnecessary to update all the content. We don't need to update the input value when Ian's just typed in their name there already. We don't need to when the user clicks we don't actually need to update the div because the user hasn't written anything so the div can just be empty.

We do it anyway because we want one simple rule. User changes data, data change triggers or we may remember to run a complete converter of that data to all associated dependent underlying view. We're getting very close people to having a full restricted implementation of user interface engineering or the user interface design pattern.

They call it a pattern for structuring, building out a user interface that has become the trademark structure for engineers. And it's the bit that even if we like to joke, spin up a virtual DOM or whatever. It's a bit if you were building your own sort of small app or not even small but app without using a framework it would be surprising for me if you didn't say let's start with all possible data that can determine all possible sets of views in the application.

And then let's have some sort of, we'll break them up into functions but we'll start with state and data in JavaScript. And everything the user can see will be derived from that underlying data. And then any handling of user's actions will start by changing the data and then will convert back to what the user sees.

Not any action by the user which is what we used to do by the way, very standard go and change what the user sees based off that action. Any action by the user must change underlying data and then a single standardized converter function which works for all conditions.

We don't even have to think about that, that's too much to think about. And to a fault by the way, that means as you can see we're gonna be updating content unnecessarily. But our computers are pretty damn fast they can definitely take a bit of unnecessary updating. Our computer can put up with updating a few unnecessary pieces of content for the gains of our time to work out which bits to update.

Have one description of what's going to show up and a bunch of conditional logic for the different conditions. And then update the data on the users action and [SOUND] update the view and that's what we're going to do. I will say, don't worry people in practice at any scale we're gonna need to be more efficient under the hood.

That's what we'll see when we talk about performance, diffing algorithms, state hooks, all these sort of things. But on a small application, honestly, it's not entirely clear you would need to spin up your own implementation of the virtual DOM. Probably because all you could do little sub pieces of it.

You could do some little pieces that kind of in egregious situations, make sure you're not repopulating or break down your functions to your updater to be only applying to some bits of the page. So, you're not going to reload all the content.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now