In this lesson, we'll learn how we can call ReactDOM.render repeatedly with brand new React Elements and React will preserve element focus
and only do the minimal required DOM operations for the re-render.
Instructor: [00:00] What we have here is a little app that's going to show us the current time. Unfortunately, it's only showing us the time since the last refresh. I refresh the page and I'm going to get the new time. I refresh again and I'm going to get the new current time.
[00:12] I want that to update automatically every second. What we can do here is, I'm going to take this stuff here, and create a function out of it. I'm going to call this tic.
[00:24] Then, I'm going to call tic and I refresh. We're still getting the same thing as we had before. I can refresh and refresh, and I'm going to get the update.
[00:32] Then, I'm just going to say set interval tic 1000. Every 1000 milliseconds it's going to update.
[00:41] Great, now we have this thing working just perfectly. If I right-click here, going to inspect that in particular. The browser is going to highlight the changes in purple here, and that's what we're getting right here is the seconds are updating.
[00:58] This is actually a little bit more important than you might think. To illustrate this, I'm going to change this to be an input that has the value of that time. If I refresh here, I'm going to get that in an input, and what's neat here is, every single time this is updating, my focus remains in the same input.
[01:20] If I go ahead and we'll just duplicate this input once here, I'm going to have two inputs here now. I can tab between the two and my focus is going to stay on the correct input. Let's see why this is kind of neat.
[01:35] I'm going to change this from JSX to a template string. Instead of ReactDOM render, I'm going to say rootelement.innerhtml equals that element, so that string. Of course I'm going to need to have this interpolated, because this is a template string.
[01:58] If I refresh here, I'm going to get the exact same thing that we had before. There's a subtle difference in how things are working here. Now, I'm getting an update of the entire DOM structure every single time this second tics.
[02:12] If I click on here, I'm going to lose focus. I click on here, I lose focus. What's really neat about the way that React is doing this for us is, we have a re-render every single second, re-render our entire application, and it's only updating the parts that actually matter, and it's maintaining focus for us.
[02:31] It makes sure that when I'm focused on the input and it re-renders, it's going to keep me focused in that input. This has really great implications for accessibility as well as performance, that it's only doing the DOM operations that are absolutely critical and necessary for React to do its updating.
[02:48] Normally, you're not going to do a full-application re-render every second, or whenever any state in your application changes, there are other ways that React exposes for you to re-render certain parts of your application based off of state changes. I wanted to show you this to illustrate to you that whenever you re-render on the same element or whenever React is doing a re-rendering, it is only going to be updating the part of the DOM that's necessary for it to re-render.
If you use defaultValue
instead of value
your initial value can not be updated.
Simply use readonly
to suppress the warning or supply a handler.
<input readOnly value={time} />
I am getting the below warning, and settimeout function is not being called, I have tried using defaultValue instead of value, but it does not work too. Do you know why is it not rerendering the time?
Warning: Failed prop type: You provided a
value
prop to a form field without anonChange
handler. This will render a read-only field. If the field should be mutable usedefaultValue
. Otherwise, set eitheronChange
orreadOnly
. in input in divmy babel code
<script type=text/babel> function tick(){ const time = new Date().toLocaleTimeString(); const element = <div>it is <input value={time}/></div> ReactDOM.render(element, document.getElementById('root')); } tick(); setTimeout(tick, 1000); </script>