Hus*_*oms 2 reactjs react-hooks use-effect
我遇到一个问题,我使用扩展运算符设置状态,但函数调用useEffect仅将从 API 拉出的最后一个值设置为状态。
// get all events to display on load
const getEvents = () => {
console.log(props.id);
axios.get(API.EVENTS.ROOT + props.id).then(
res => {
const data = res.data;
setEvent(data);
console.log(data);
// event start and end dates
setStart(new Date(data.start));
setEnd(new Date(data.finish));
// breakout dates
for (let i = 0; i < data.breakouts.length; i++) {
console.log(data.breakouts[i].start);
data.breakouts[i].start = new Date(data.breakouts[i].start);
data.breakouts[i].end = new Date(data.breakouts[i].end);
console.log(data.breakouts[i].name, "test" + data.breakouts[i].start);
// set date picker initial value
setFields({
...fields,
[data.breakouts[i].name]: data.breakouts[i].start
})
console.log(fields);
}
setBreakoutRow(data.breakouts);
console.log(breakoutRow);
}
).catch(err => {
console.log(err);
})
}
// get events on load
useEffect(() => {
console.log(props);
getEvents();
}, []);
Run Code Online (Sandbox Code Playgroud)
我添加字段状态变量或getEvents函数作为依赖项,它确实会更新state所有值的字段,但会导致无限的死亡循环。这使得除了最后一行之外的所有映射行中的日期均为空白。
另一件值得注意的事情是,页面加载后,可以通过函数调用毫无问题地更新 fields 对象,如下所示:
const handleDateChange = (dateName, dateValue) => {
console.log(dateName, dateValue);
setFields({
...fields,
[dateName]: dateValue
})
console.log(fields);
}
Run Code Online (Sandbox Code Playgroud)
这让我相信我的钩子有问题useEffect,但我不确定哪里出了问题。
原因是您如何访问以前的值来添加新元素:
for (let i = 0; i < data.breakouts.length; i++) {
data.breakouts[i].start = new Date(data.breakouts[i].start);
setFields({
...fields,
[data.breakouts[i].name]: data.breakouts[i].start
})
}
Run Code Online (Sandbox Code Playgroud)
由于fields仅在下一次渲染时更新,因此您将单个元素(但每个循环都是不同的元素)添加到数组中。
没有 hooks/react 也是一样的:
const start = [];
for(let i = 0; i< 5; i++) console.log([...start, i]);
Run Code Online (Sandbox Code Playgroud)
这永远不会输出[0,1,2,3,4]。
你能做什么。
const temp = {};
for (let i = 0; i < data.breakouts.length; i++) {
data.breakouts[i].start = new Date(data.breakouts[i].start);
data.breakouts[i].end = new Date(data.breakouts[i].end);
temp[data.breakouts[i].name] = data.breakouts[i].start
}
setFields({
...fields,
...temp
});
Run Code Online (Sandbox Code Playgroud)
for (let i = 0; i < data.breakouts.length; i++) {
data.breakouts[i].start = new Date(data.breakouts[i].start);
setFields(({fields: prevFields}) => ({
...prevFields,
[data.breakouts[i].name]: data.breakouts[i].start
}))
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢第一个选项,原因有两个:
axios.get就不需要一些API.getMeaningfullThings返回结构;所以重构起来更容易| 归档时间: |
|
| 查看次数: |
4847 次 |
| 最近记录: |