该应用程序工作正常,并将添加的数据添加到本地主机,但是当我重新加载时,我丢失了数据,但它应该来自本地主机。看来我使用 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;
这是因为您处于 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')));
}
}, []);
我想问题就出在这里
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('');
}
您可以使用类似的方法来删除功能。