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 state is not updating with localStorage

I m working with localstorage. I have some toDos list(its name savedToDos in my code) there and now I m working on button that allows to save changes after editing values of toDos. I save changes in localStorage and then I try to update state to get fresh data from localstorage, but it is not working, changes are not showing correctly. It is working only when I reload page – all changes are showing correctly. Otherwise I’ve seen in console that localStorage is updating correctly, but when I try to update state with localStorage, state is just doesn’t updating, only after reload of page. And without reloading toDo list is showing incorrect updates.

Here is code, main thought in function saveToDo

export default function Bar() {

    const LOCAL_TO_DOS = "localToDos"
    const [toDo, setToDo] = React.useState("")
    const [savedToDos, setSavedToDos] = React.useState([])
    const barInput = document.getElementById("barInput")
    const inputRef= React.useRef(null)
    //localStorage.clear()

    React.useEffect(()=>{
        if(localStorage.getItem(LOCAL_TO_DOS)) {      
            setSavedToDos(
                JSON.parse(
                    localStorage.getItem(LOCAL_TO_DOS)
                )
            )
        }
    }, [])

    function handleChange(event){
        setToDo(event.target.value)
    } 
    
    function addNewToDo(){
        if(toDo){
            const localToDo = {
                id: nanoid(), 
                content: toDo
            }
            setSavedToDos([...savedToDos ,localToDo])
            localStorage.setItem(
                LOCAL_TO_DOS, 
                JSON.stringify([...savedToDos,localToDo])
            )
            setToDo("")
            barInput.value = ""
            inputRef.current.focus()
        }
    }
    
    function editToDo(event){
        //if were changes  
        document.getElementById(event.target.parentNode.id)
            .contentEditable="true"
        document.getElementById(event.target.id)
            .style.visibility = "hidden"
        document.getElementById(event.target.id)
            .nextElementSibling.style.visibility = "visible"
    }

    function saveToDo(event){
        document.getElementById(event.target.parentNode.id)
            .contentEditable="false"
        document.getElementById(event.target.id)
            .style.visibility = "hidden" 
        document.getElementById(event.target.id)
            .previousElementSibling.style.visibility = "visible"

        const editedToDo = {
            id: event.target.parentNode.id, 
            content: document.getElementById(
                event.target.parentNode.id
            ).childNodes[0].nodeValue
        }

        let updatedToDos = savedToDos.filter(note => 
            note.id != event.target.parentNode.id
        )
        localStorage.setItem(
            LOCAL_TO_DOS, 
            JSON.stringify([editedToDo,...updatedToDos])
        )

        setSavedToDos(
            JSON.parse(localStorage.getItem(LOCAL_TO_DOS))
        )
    }

    return (
        <div className='bar'>
            <textarea
                ref={inputRef}
                id="barInput"
                //type="text"
                placeholder="new to-do"
                onChange={handleChange}
            />
            <button id="addButton" onClick={addNewToDo}>add</button>
            {savedToDos.length != 0? <>
        {savedToDos.map((savedToDo)=>(
            <div className="toDoArea"  id={savedToDo.id}>
        {savedToDo.content}
        <button  id={nanoid()} className="editButton" onClick={editToDo}>edit</button>
        <button  id={nanoid()} className="saveButton" onClick={saveToDo}>save</button>
        <button  id={nanoid()} className="deleteButton" onClick={deleteTodo}>delete</button>
        </div>
        )) }</> : <p>You have not any tasks</p>}
    </div>
  )
}

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

>Solution :

It’s updating correctly on reload because your useEffect is correctly fetching the updated values from localStorage, but in your saveToDo function, you should set the value directly instead of trying to refetch from localStorage. i.e.

setSavedToDos([editedToDo,...updatedToDos])

So your function should look like this:

function saveToDo(event){
    document.getElementById(event.target.parentNode.id).contentEditable="false"
    document.getElementById(event.target.id).style.visibility = "hidden"
    document.getElementById(event.target.id).previousElementSibling.style.visibility = "visible"

       const editedToDo = {
        id:event.target.parentNode.id, 
        content:document.getElementById(event.target.parentNode.id).childNodes[0].nodeValue
    }
    let updatedToDos = savedToDos.filter(note => note.id != event.target.parentNode.id)
    localStorage.setItem(LOCAL_TO_DOS, JSON.stringify([editedToDo,...updatedToDos]))
    setSavedToDos([editedToDo,...updatedToDos])
}

That should update the array correctly. The localStorage item should just be to ensure that your to-do list is still available on reloading the page.

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