如何在React组件中每分钟调用一个函数?

33

我制作了一个表格来获取股票报价,它运作良好,但是当我尝试在组件中放置包含setState的函数时,它会陷入无限循环,触发setState并立即重新渲染并再次触发。

我该如何在加载此组件时调用此函数而不触发无限循环? 我想每10秒或每分钟调用一次这个函数。

import React, { useState } from 'react'
import api from '../../api'

function CreateRow(props){
    
    const [stock, setStock] = useState({symbol:'',last:'',change:''})
    

    async function check() {
        const result = await api.getStock(props.item)
        console.log(props.item)
        const symbol = result.data.symbol
        const lastest = result.data.latestPrice
        const change = result.data.change
        setStock({symbol:symbol, lastest:lastest, change:change})
    }


    // check()   <----------! if I call the function here, it becomes an infinite loop.


    return(
        <tr>
            <th scope="row"></th>
            <td>{stock.symbol}</td>
            <td>{stock.lastest}</td>
            <td>{stock.change}</td>
        </tr>
    )
}

export default CreateRow

1
尝试在useEffect中使用setTimeout。 - Elanochecer
4个回答

93

你想在生命周期方法中启动一个超时函数。

生命周期方法是调用挂载和卸载(还有更多例子,但为了解释起见,我会在这里停止)的方法。

你感兴趣的是挂载生命周期。

在函数组件中,可以像这样访问:

import { useEffect } from 'react';

useEffect(() => {
  // This will fire only on mount.
}, [])
在那个函数中,你想要初始化一个 setTimeout 函数。
const MINUTE_MS = 60000;

useEffect(() => {
  const interval = setInterval(() => {
    console.log('Logs every minute');
  }, MINUTE_MS);

  return () => clearInterval(interval); // This represents the unmount function, in which you need to clear your interval to prevent memory leaks.
}, [])

3
答案看起来很好,只是我想提醒一下,在useEffect之外声明const MINUTE_MS = 60000;,这样我们就不必在每次迭代时重新声明变量了。 - Pedro Ferrari
2
@PedroFerrari 完全同意,我甚至会更进一步地将其保留在 constants.js 文件中以获得更好的一致性。我会编辑我的代码,谢谢! - Antonio Erdeljac
2
这个答案应该被标记为已接受的答案。 - Or Assayag
clearInterval(interval) 为什么很重要呢?这不会取消您设置的间隔吗? - Kid_Learning_C
1
@Kid_Learning_C 这样可以避免组件消失时间隔仍在运行。 - user275564

2
考虑60000毫秒=1分钟
可以使用以下方法:
setInterval(FunctionName, 60000)

做如下操作:
async function check() {
  const result = await api.getStock(props.item)
  console.log(props.item)
  const symbol = result.data.symbol
  const lastest = result.data.latestPrice
  const change = result.data.change
  setStock({symbol:symbol, lastest:lastest, change:change})
}

// Write this line

useEffect(() => {
  check()
 }, []);


setInterval(check, 60000);

1
import React, { useState, useEffect } from "react";

export const Count = () => {
const [currentCount, setCount] = useState(1);

useEffect(() => {
 if (currentCount <= 0) {
   return;
 }

 const id = setInterval(timer, 1000);
 return () => clearInterval(id);
}, [currentCount]);

const timer = () => setCount(currentCount + 1);

console.log(currentCount);

return <div>Count : - {currentCount}</div>;
};

0

你也可以使用setTimeout来实现这个功能

import React, { useState, useEffect } from "react";

export const Count = () => {
const [counts, setcounts] = useState(0);

async function check() {
  setcounts(counts + 1);
}

// Write this line
useEffect(() => {
check();
}, []);

 console.log("hello dk - ",counts)

 setTimeout(() => {
    check();
   }, 1000);

return <div>Count : - {counts}</div>;

};


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接