用lodash和setInterval反应问题

问题描述

我在使用Lodash + setInterval时遇到问题。

我想做什么: 每3秒随机检索我对象的一个​​元素

这是我的对象

    const [table,setTable]= useState ([]);

所以我从那开始:

const result = _.sample(table);
   console.log(result);

控制台提供=>对象{标签:“ figue”,labelEn:“ fig”}

但是如果添加

const result = _.sample(table);
   console.log(result.label);

控制台提供=> TypeError:结果未定义

除了我尝试添加setInterval并尝试使用useEffect之外,还是代码崩溃或控制台每3秒给我两个数字=> 2,6,2,6 ......

解决方法

Ciao,假设table对象是正确填充的,则可以使用lodash和{{来使用setIntervaltable来获得useEffect的随机对象1}}钩子,如:

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用值填充(否则会出现错误)。

要解决此问题,仅需要在第一个tableuseEffect)上放置另一个条件,然后在第二个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);
      },[table]);

Here代码和框已更新。

,

问题是您在加载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);

// ...