My background is WPF/Winforms and I am just starting to learn React. From my understanding, on every keypress, the following code will re-render, and so will re-generate the elements including the text box. So the old textbox is thrown away and a new one created (losing focus).
So if the old textbox has focus, and a new textbox is then created after I press a key, how is it that the new text box still has the focus?
Interestingly, when I google this, people seem to experience what I expected, in that you would have to refocus the textbox after each key press. Yet for me, it seems to magically work.
I am guessing that React is being a little smarter here and recycling the elements? or is it still re-creating a new textbox, but restoring focus behind the scenes?
function App() {
const [userText, setUserText] = useState("empty")
return (
<>
<p>{userText}</p>
<input type='text' value={userText} onChange={e => setUserText(e.target.value)}/>
</>
)
}
export default App
4
I am guessing that React is being a little smarter here and recycling
the elements? or is it still re-creating a new textbox, but restoring
focus behind the scenes?
Perhaps the answer to this question included in the question itself.
The point is React definitely does not re-create the input element in the code. Even the term Recycling may be a little inaccurate. The most suiting term may be update, React updates the element in this case.
The reason for saying that the question has the answer, the question is saying that React is restoring focus behind the scenes. However then a question comes here is that the latest JSX returned by the latest re-render does not have any information about the element focus, it does not carry any information about it. Therefore from where does React get the information about the focus to restore ? There is no other way than to get it from the element itself. It means the element as such – with all of its properties and values, is retained in the DOM, therefore there is nothing to do extra to retain the focus.
Now with respect to each key stroke, which is happening here. The state userText is getting updated. Since this is a state updating, the component will re-render, that too on every key stroke. However, each JSX newly returned per key stroke differs from its just previous JSX only by the props value. The value prop will keep on getting the latest text in the state. Therefore in order to synch the latest JSX with the respective DOM element, it just needs to only “update’ the value property of the same input DOM element. That way, React does only the minimal necessary operations to make the DOM element in synch with the latest JSX.
As you know, we have been discussing so far about a controlled input.
Let us take a case of an uncontrolled input. The below code shows the same.
Here, even though the component re-renders on every 5 second, the input made during the run-time has been retained. Please recall that it is an uncontrolled input and therefore no state has been backed up the same. Still the input during the run-time has been retained. It clarifies React does not touch the input element on every render.
App.js
import { useState, useEffect } from 'react';
export default function App() {
const [autoRender, setAutoRender] = useState();
useEffect(() => {
const timer = setInterval(() => {
setAutoRender(Math.random());
}, 5000);
return () => clearInterval(timer);
}, []);
return (
<>
<h3>A component auto-renders in 5 seconds</h3>
<label>
An uncontrolled input still retains your input on every render
</label>
<input />
<br />
<br />
<i>The latest state : {autoRender}</i>
</>
);
}
Test run
The concluding points are :
-
When an App starts, it does its initial Render. During this initial render, every element in the JSX returned has to be created in the DOM. React uses the API appendChild() to create all these elements. There is no optimisation React can do here.
-
However, on every subsequent render, Reacts compares the latest JSX with the just previous JSX. Thus it finds the delta of JSX. React updates DOM with respect to this delta of JSX only. This may include element removal, element addition and element updating. It is all depending on the rendering logic in the component. This is the time React can really make the difference. It essentially optimises DOM updating.
Citation:
Step 3: React commits changes to the DOM
1