In the React document, it mentions that when rendering a list without keys, React will mutate every child instead of realizing it can keep the items subtrees intact. This inefficiency can be a problem.
I am wondering how I can verify this kind of impact, for example this is the demo I’m writing now:
let renderCount = 0;
function City({ name }) {
console.log('renderCount:', ++renderCount)
return <li>{name}</li>
}
export default function Page() {
const [cities, setCities] = useState(['New York', 'Chicago', 'San Francisco'])
return (
<>
<button onClick={() => setCities(['Beijing', ...cities])}>Add new city</button>
<div>
{cities.map(city => (
<City key={city} name={city} />
))}
</div>
</>
)
}
No matter if I add the key on the city element or not, after I click the button the render count value finally will be 7. Or is there another way like render time to prove the key works?
>Solution :
Using keys doesn’t change the number of renders of the virtual DOM, it changes the number of differences that react calculates when it does reconciliation. And this in turn affects how many changes it must then push to the real DOM.
With keys, your example results in react inserting one <li> to the DOM at the front of the list, with the text "Beijing". Without keys, react will update the 1st <li> to have the text "Beijing" instead of "New York", the 2nd <li> to have the text "New York" instead of "Chicago", the 3rd <li> to have the text "Chicago" instead of "San Francisco", and will insert a 4th <li> at the end with the text "San Francisco"
Since this happens after your code has returned you don’t have a direct way to measure it, but dev tools should be able to help. In google chrome’s developer tools, press ctrl-shift-p (i think on mac it’s command-shift-p) and type and select "show paint flashing rectangles" to highlight which parts of the page are being updated. Or you could make the list really long (thousands at least) so that the number of updates causes a delay that is noticeable as a user.
Ps: In addition to performance concerns, the lack of keys has other implications. If the child components have state or can be focused, that react state or focus state may be unexpected reset, or may now correspond with an element you weren’t expecting.