我正在构建一个应用程序来跟踪习惯,当用户被定向到仪表板时,我希望他们立即看到他们的习惯是从数据库中提取的。我曾尝试从 useEffect 中调用 useState,但我知道这样做存在固有的问题。我尝试为 useEffect 提供第二个参数来解决此问题,但仍然收到无效的钩子调用错误。
const Dashboard = () => {
const [refetch, setRefetch] = useState(true);
const [habits, setHabits] = useState([]);
useEffect(() => {
if(refetch){
fetch('/habits/getHabits', {
method: "POST",
headers: {"Content-Type": "application/json; charset=UTF-8"},
body: JSON.stringify({username: 'Phil'})
})
.then((data) => data.json())
.then((data) => {
const habitCards = [];
for(let habit of data.habits){
habitCards.push(
<Habit
key={habit.habitid}
habitname={habit.habitname}
moneyspent={habit.moneyspent}
lasttime={habit.lasttime}
/>
)
}
setHabits(habitCards);
})
.finally(() => setRefetch(false))
}
}, [refetch])
return (
<div className='dash'>
<h1>Your habits:</h1>
{habits}
</div>
)
}
我该如何修改它,以便仅在页面加载时调用 useEffect 并从其中更新状态?
回答1
如果你希望你的效果在页面加载时只运行一次,那么传递一个空的依赖数组 []
作为第二个参数。
当你传递一个空的依赖数组时,你是在告诉 React 这个效果不依赖于来自 props 的任何 values 或状态,并且它永远不需要重新运行。
useEffect(() =>
{
fetch('/habits/getHabits', {
method: "POST",
headers: {"Content-Type": "application/json; charset=UTF-8"},
body: JSON.stringify({username: 'Phil'})
})
.then((data) => data.json())
.then((data) => {
const habitCards = [];
for(let habit of data.habits){
habitCards.push(
<Habit
key={habit.habitid}
habitname={habit.habitname}
moneyspent={habit.moneyspent}
lasttime={habit.lasttime} />
)
}
setHabits(habitCards);
})
}, [])
在这种情况下,您将不再需要 refetch
状态变量。
您可以在https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects阅读更多关于跳过效果的信息。