Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

131
Views
React, localStorage is not persistent upon page refresh

I'm new to React and I can't understand what's wrong with my use of the useEffect hook. The code is compiled successfully and everything seems to work. The components added by the user are shown on the browser and added to localStorage but upon refresh, only the example component is shown (Box 1) and the input done by the user is lost. Any idea on what could be the issue?

mport React, { Fragment, useState, useRef, useEffect } from 'react';
import { v4 as uuidv4} from 'uuid';
import { BoxList } from './components/BoxList';
import { SearchBox } from './components/SearchBox';

const KEY = "boxApp.boxes";

export function App() {
  const [boxes, setBoxes] = useState([ {id: 1, title: 'Box 1', content: 'This is just an example of a box, remove it and create yours!' } ])
  
  const boxTitleRef = useRef();
  const boxContentRef = useRef();

  useEffect(() => {
    const storedBoxes = JSON.parse(localStorage.getItem(KEY));
    if (storedBoxes) {
      setBoxes(storedBoxes);
    }
  }, []);

  useEffect(() =>{
    localStorage.setItem(KEY, JSON.stringify(boxes));
  }, [boxes]);

  const removeBox = (id) => {
    const remainingBoxes = boxes.filter((box) => box.id !== id);
    setBoxes(remainingBoxes);
  }

  const addNewBox = (evt) => {
    evt.preventDefault();
    const boxTitle = boxTitleRef.current.value;
    const boxContent = boxContentRef.current.value;
    if (boxTitle === '' || boxContent === '') return;
    setBoxes( previousBoxes => {
      return ([...previousBoxes, { id: uuidv4(), title: boxTitle, content: boxContent}])
    });

    boxTitleRef.current.value = null;
    boxContentRef.current.value = null;
  }

  return (
    <Fragment>
      <SearchBox  />
      <div>
        <h2>Add a box</h2>
        <form>
         <input type='text' placeholder='Title' ref={boxTitleRef}></input>
          <input type='text' placeholder='Content' ref={boxContentRef}></input>
          <button type='submit' onClick={addNewBox}>➕</button>
        </form>
      </div>
      <BoxList boxes={boxes} removeBox={removeBox}/>
    </Fragment>
  );
}

export default App;
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

The problem is coming from the below useEffect that you have:

useEffect(() =>{
   localStorage.setItem(KEY, JSON.stringify(boxes));
}, [boxes]);

It updates the localStorage every time boxes changes, but also when the component gets mounted the first time, and at this point boxes is equal to that initial state given to useState. You could remove it, and update the localStorage when adding and removing items:

const addNewBox = (evt) => {
  evt.preventDefault();
  const boxTitle = boxTitleRef.current.value;
  const boxContent = boxContentRef.current.value;
  if (boxTitle === "" || boxContent === "") return;
  const newBoxes = [...boxes, { id: uuidv4(), title: boxTitle, content: boxContent }];
  setBoxes(newBoxes);
  localStorage.setItem(KEY, JSON.stringify(newBoxes));
  boxTitleRef.current.value = null;
  boxContentRef.current.value = null;
};
const removeBox = (id) => {
  const remainingBoxes = boxes.filter((box) => box.id !== id);
  localStorage.setItem(KEY, JSON.stringify(remainingBoxes));
  setBoxes(remainingBoxes);
};

You coud also change your useState call to this:

const [boxes, setBoxes] = useState(JSON.parse(localStorage.getItem(KEY)) || [ {id: 1, title: 'Box 1', content: 'This is just an example of a box, remove it and create yours!' } ]);

And remove the following useEffect that you have:

useEffect(() => {
  const storedBoxes = JSON.parse(localStorage.getItem(KEY));
  if (storedBoxes) {
    setBoxes(storedBoxes);
  }
}, []);
about 4 years ago · Juan Pablo Isaza Report

0

It should solve your problem if you set your initial state value conditionaly from local storage like this.

Here is the piece you need to update

const initialValue = JSON.parse(localStorage.getItem(KEY));
const [boxes, setBoxes] = useState(initialValue ? initialValue : [ {id: 1, title: 'Box 1', content: 'This is just an example of a box, remove it and create yours!' } ])
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!