[英]React issue with lodash and setInterval
I have an issue with using Lodash + setInterval.我在使用 Lodash + setInterval 时遇到问题。
What I want to do: Retrieve randomly one element of my object every 3 seconds我想做的是:每 3 秒随机检索我的 object 中的一个元素
this is my object:这是我的 object:
const [table, setTable]= useState ([]);
so I start with that:所以我从那开始:
const result = _.sample(table);
console.log(result);
console give => Object { label: "Figue", labelEn: "fig" } console give => Object { label: "Figue", labelEn: "fig" }
But if a add:但如果添加:
const result = _.sample(table);
console.log(result.label);
console give => TypeError: result is undefined控制台给出 => 类型错误:结果未定义
Beside that I tried to add setInterval and also try with useEffect but or code crash or console give me two numbers every 3 second => 2,6,2,6......除此之外,我尝试添加 setInterval 并尝试使用 useEffect 但是或代码崩溃或控制台每 3 秒给我两个数字 => 2,6,2,6 ......
Ciao, supposing that table
object is correclty filled, you could use lodash
and setInterval
to get random object of table
using useEffect
and useRef
hooks like:再见,假设
table
object 已正确填充,您可以使用lodash
和setInterval
使用useEffect
和useRef
挂钩随机获取table
object,例如:
const interval = useRef(null);
useEffect(() => {
if (!interval.current) {
interval.current = setInterval(() => {
const result = _.sample(table);
console.log(result.label);
}, 3000);
}
}, [table]);
Then to clean setInterval
when component will be unmount you could use another useEffect
in this way:然后要在卸载组件时清理
setInterval
,您可以通过这种方式使用另一个useEffect
:
useEffect(() => {
return () => {
clearInterval(interval.current);
interval.current = null;
};
}, []);
EDIT编辑
After your explanation, I found the cause of your problem.经过你的解释,我找到了你问题的原因。 Before start
setInterval
you have to wait that table
was filled with values (otherwise you get an error).在开始
setInterval
之前,您必须等待table
中填满值(否则会出现错误)。
To solve that it's just necessary to put another condition on first useEffect
( table.length > 0
), and load data on second useEffect
.要解决这个问题,只需要在第一个
useEffect
( table.length > 0
) 上加上另一个条件,然后在第二个useEffect
上加载数据。
So the first useEffect
becomes:所以第一个
useEffect
变成了:
const interval = useRef(null);
useEffect(() => {
if (!interval.current && table.length > 0) {
interval.current = setInterval(() => {
const result = _.sample(table);
console.log(result.label);
}, 3000);
}
}, [table]);
And the second one:第二个:
useEffect(() => {
jsonbin.get("/b/5f3d58e44d93991036184474/5")
.then(({data}) => setTable(data));
return () => {
clearInterval(interval.current);
interval.current = null;
};
}, []);
The problem is that you access table
before it is loaded.问题是您在加载表之前访问
table
。
You should either provide an initial value to that allows a successful do all your operations:您应该提供一个允许成功执行所有操作的初始值:
// use an array that has at least one element and a label as initial table value
const [table, setTable] = useState([{label: "default label"}]);
useEffect(() => {
jsonbin.get("/b/5f3d58e44d93991036184474/5")
.then(({data}) => setTable(data));
});
const result = _.sample(table);
console.log(result.label);
// ...
Or use an if
or something alike to handle multiple scenarios:或者使用
if
或类似的东西来处理多个场景:
// use an empty array as initial table value
const [table, setTable] = useState([]);
useEffect(() => {
jsonbin.get("/b/5f3d58e44d93991036184474/5")
.then(({data}) => setTable(data));
});
const result = _.sample(table);
// account for the initial empty table value by checking the result
// of _.sample which is `undefined` for empty arrays
if (result) {
console.log(result.label);
} else {
console.log("do something else");
}
// ...
If you fetch your data asynchronously you must think about what you want to use while the data is being fetched.如果您异步获取数据,则必须考虑在获取数据时要使用什么。 The minimal thing to do is tell React to not render the component while the data is missing (being fetch).
最简单的事情是告诉 React 在数据丢失(正在获取)时不要渲染组件。
const [table, setTable] = useState([]);
useEffect(() => {
jsonbin.get("/b/5f3d58e44d93991036184474/5")
.then(({data}) => setTable(data));
});
const result = _.sample(table);
if (!result) return null; // <- don't render if there is no result
console.log(result.label);
// ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.