Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React preserving state even though key has changed

The react component is preserving the "wasEdited" state even when the properties and key are changed. When any div element is edited from its initial value, the classname of the div row will be changed, thus showing a red border on the left side.

I was able to get around the issue by resetting the state manually every time the "globalId" property is changed. As you can see in the comment, I suspect this may be a similar issue to this:

React does not re-render updated map, even with different keys

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But in my case I’m not mutating an object.

function Attribute ({globalId, name, value}) {
    const [wasEdited, setWasEdited] = useState(false);

    const handleInput = (e) => {
        e.target.innerHTML === value ? setWasEdited(false) : setWasEdited(true);
    };

    // TODO: This useEffect is a hack to reset the wasEdited state when the globalId changes. I don't understand
    // why this is necessary, since each Attribute component is rendered with a unique key. I think it
    // has something to do with this post on [stack overflow](https://stackoverflow.com/questions/68949376///react-does-not-re-render-updated-map-even-with-different-keys).
 

    // useEffect(() => {
    //     return () => setWasEdited(false);
    // }, [globalId])

    console.log(`${globalId}-${name}`, wasEdited)

    return (
        <div key={`${globalId}-${name}`} className={wasEdited ? 'row was-edited' : 'row'}>
            <div className='col'>{name}</div>
            <div className='col' onInput={handleInput} contentEditable>{value}</div>
        </div>
    )
}

This is what it looks like:
This is what it looks like

>Solution :

Putting a key on a div will cause that div to unmount and remount when the key changes. But it will have no effect on the component surrounding that div (Attribute). If you want to deliberately unmount and remount Attribute, you need to put a key on Attribute. So wherever you’re rendering it, do:

<Attribute key={`${globalId}-${name}`} globalId={globalId} name={name} value={something} />
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading