Рендеринг / обновление списка, хранящегося в локальном хранилище

#reactjs

#reactjs

Вопрос:

Я пытаюсь отобразить список на основе объекта с именем todos. Я хочу, чтобы это сохранялось после того, как пользователь перейдет со страницы. Когда пользователь добавляет объект to do, он сохраняется локально и используется для обновления объекта todos с использованием state. Задачи отображаются в списке неправильно, поэтому мне интересно, что я делаю не так.

Объект Todos:

 const [todos, setTodos] = useState([
  {
    text: "Learn about React",
    isCompleted: false,
    id: uuid()
  },
]);
  

Добавить функцию (обновление задач здесь, которая должна повторно отобразить мой список):

 const addTodo = text => {
  setTodos([{text, isCompleted: false, id: uuid()}, ...todos]);   //updates todos object
  localStorage.setItem("currList", JSON.stringify(todos));        //saves new todos object
  storedCurrList = localStorage.getItem("currList");              //retrieves new object
  parsedList = JSON.parse(storedCurrList);                        //parses object
  setTodos(parsedList);                                           //updates based on local save
};                                                                //object so that the update persists
  

Компонент, который отрисовывает задачи:

 {todos.map((value, index) => {
   return(
     <ListItem key={todos.id}> 
       <ListItemIcon>
         <Checkbox
           edge="start"
           checked={value.isCompleted}
           onChange={() => removeTodo(index)}
           tabIndex={-1}
           disableRipple
          />
       </ListItemIcon>
       <ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35, color: nightMode.listText}} primary={value.text}/>
     </ListItem>
   );
 })}
  

Ответ №1:

Если вы не хотите отображать todos из localStorage , вы должны сначала прочитать его, а затем установить это в качестве своего начального todos состояния.

 const [todos, setTodos] = React.useState([]); // todos are empty by default

React.useEffect(() => {
  // reads the todos saved from localStorage and set that as the new value
  // of our todos state — if currList not found, will fallback to empty list
  const savedTodos = JSON.parse(localStorage.getItem("currList")) || [];
  setTodos(savedTodos);
}, []);
  

Теперь при обновлении todos вкл localStorage измените свой addTodo обработчик на

 const addTodo = text => {
  // we'll use this to update our `todos` state and `localStorage` 
  const newTodos = [
    { text: input, isCompleted: false, id: uuid() },
    ...todos
  ];

  setTodos(newTodos);
  localStorage.setItem("currList", JSON.stringify(newTodos));
};

  

Когда вы делаете это (приведенный ниже код) в своей addTodo функции, todos значение, которое вы устанавливаете localStorage , остается не обновленным, todos даже если вы вызываете setTodos первым.

 setTodos([{text, isCompleted: false, id: uuid()}, ...todos]);
localStorage.setItem("currList", JSON.stringify(todos)); // todos here don't have the new todo
  

Я создал codesandbox для вас, чтобы оформить заказ, надеюсь, вы поняли идею.

Редактировать nice-shirley-mvrnb

Комментарии:

1. Сработало отлично, спасибо за подробное объяснение, которое вы дали мне для лучшего понимания локального хранилища / перехватов.