使用 lodash 和 setInterval 的 React 问题
我在使用 Lodash + setInterval 时遇到问题。
我想要做的: 每 3 秒随机检索我的对象的一个​​元素
这是我的对象:
const [table, setTable]= useState ([]);
所以我从这个开始:
const result = _.sample(table);
console.log(result);
控制台给出 => Object { label: "Figue", labelEn: "fig" }
但是如果添加:
const result = _.sample(table);
console.log(result.label);
控制台给出 => TypeError: 结果未定义
除此之外,我尝试添加 setInterval 并尝试使用 useEffect 但代码崩溃或控制台每 3 秒给我两个数字 => 2,6,2,6 ......
你好,假设
table
对象已正确填充,您可以使用
lodash
和
setInterval
获取
table
的随机对象,使用
useEffect
和
useRef
钩子,例如:
const interval = useRef(null);
useEffect(() => {
if (!interval.current) {
interval.current = setInterval(() => {
const result = _.sample(table);
console.log(result.label);
}, 3000);
}
}, [table]);
然后,要在卸载组件时清理
setInterval
,您可以使用另一个
useEffect
,方式如下:
useEffect(() => {
return () => {
clearInterval(interval.current);
interval.current = null;
};
}, []);
编辑
经过您的解释,我找到了问题的原因。在启动
setInterval
之前,您必须等待
table
已填充值(否则会出错)。
要解决这个问题,只需在第一个
useEffect
上添加另一个条件(
table.length > 0
),然后在第二个
useEffect
上加载数据。
因此,第一个
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]);
第二个为:
useEffect(() => {
jsonbin.get("/b/5f3d58e44d93991036184474/5")
.then(({data}) => setTable(data));
return () => {
clearInterval(interval.current);
interval.current = null;
};
}, []);
这里 codesandbox 已更新。
问题是您在加载
table
之前访问它。
您应该提供一个初始值,以便成功执行所有操作:
// 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);
// ...
或者使用
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");
}
// ...
如果您异步获取数据,则必须考虑在获取数据时要使用什么。要做的最少的事情是告诉 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);
// ...