请帮我解决这个useEffect问题

问题描述 投票:0回答:2

该应用程序工作正常,并将添加的数据添加到本地主机,但是当我重新加载时,我丢失了数据,但它应该来自本地主机。看来我使用 useEffect 的方式错误。请检查代码并帮助我知道我在这里做错了什么。谢谢

import { useEffect, useState } from 'react';

function PetApp() {
  const [pets, setPets] = useState([]);
  useEffect(() => {
    if (localStorage.getItem('examplePetData')) {
      setPets(JSON.parse(localStorage.getItem('examplePetData')));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem('examplePetData', JSON.stringify(pets));
  }, [pets]);

  return (
    <>
      <AddPetForm setPets={setPets} />
      <ul>
        {pets.map(pet => (
          <Pet setPets={setPets} id={pet.id} name={pet.name} species={pet.species} age={pet.age} key={pet.id} />
        ))}
      </ul>
    </>
  );
}

function AddPetForm(props) {
  const [name, setName] = useState();
  const [species, setSpecies] = useState();
  const [age, setAge] = useState();

  function handleSubmit(e) {
    e.preventDefault();
    props.setPets(prev => prev.concat({ name, species, age, id: Date.now() }));
    setName('');
    setSpecies('');
    setAge('');
  }

  return (
    <form onSubmit={handleSubmit}>
      <fieldset>
        <legend>Add New Pet</legend>
        <input value={name} onChange={e => setName(e.target.value)} placeholder="Name" />
        <input value={species} onChange={e => setSpecies(e.target.value)} placeholder="species" />
        <input value={age} onChange={e => setAge(e.target.value)} placeholder="age in years" />
        <button>Add Pet</button>
      </fieldset>
    </form>
  );
}

function Pet(props) {
  function handleDelete() {
    props.setPets(prev => prev.filter(pet => pet.id != props.id));
  }

  return (
    <li>
      {props.name} is a {props.species} and is {props.age} years old.
      <button onClick={handleDelete}>Delete</button>
    </li>
  );
}
export default PetApp;
reactjs react-hooks local-storage
2个回答
0
投票

这是因为您处于 React.Strict 模式,其中效果被调用两次,理想情况下,如果您的方法是纯方法,则应该给出相同的响应。

https://react.dev/reference/react/useMemo#my-calculation-runs-twice-on-every-re-render

您可以通过设置初始状态来解决此问题

  const [pets, setPets] = useState(()=>{
    if (localStorage.getItem('examplePetData')) {
      return JSON.parse(localStorage.getItem('examplePetData'));
    }
    return [];
  });

并删除

  useEffect(() => {
    if (localStorage.getItem('examplePetData')) {
      setPets(JSON.parse(localStorage.getItem('examplePetData')));
    }
  }, []);

0
投票

我想问题就出在这里

 useEffect(() => {
    localStorage.setItem('examplePetData', JSON.stringify(pets));
  }, [pets]);

每当宠物值发生变化时,您都将其设置为本地存储,现在当应用程序加载时,空数组将保存在本地存储中,从而成为空数据。

让我们有一个新功能

const handleSetPets = (newPet) => {
    setPets([...pets, newpet]);
    localStorage.setItem('examplePetData', JSON.stringify(pets));
}

现在将此函数传递给

AddPetForm
<AddPetForm handleSetPets={handleSetPets } />

最后在AddPetForm中 而不是直接调用 setPets 这样做

  function handleSubmit(e) {
    e.preventDefault();
    props.handleSetPets({name, species, age, id: Date.now() });
    setName('');
    setSpecies('');
    setAge('');
  }

您可以使用类似的方法来删除功能。

© www.soinside.com 2019 - 2024. All rights reserved.