Как вызывать функцию каждую минуту в компоненте React?

#javascript #reactjs #react-redux #react-hooks

#javascript #reactjs #react-redux #реагирующие хуки

Вопрос:

Я создаю таблицу для получения котировок акций, она работает хорошо, но когда я пытаюсь поместить функцию include 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 внутри него.

Ответ №1:

Вы хотите инициировать функцию тайм-аута внутри метода жизненного цикла.

Методы жизненного цикла — это методы, которые вызывают, например, монтирование и размонтирование (есть и другие примеры, но ради объяснения я остановлюсь здесь)

что вас интересует, так это жизненный цикл монтирования.

В функциональных компонентах к ней можно получить доступ следующим образом:

 const { 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.
}, [])
 

Комментарии:

1. Ответ выглядит для меня великолепно, на крошечной маленькой заметке я бы объявил const MINUTE_MS = 60000; вне useEffect, поэтому нам не нужно повторно объявлять переменную на каждой итерации

2. @PedroFerrari абсолютно согласен, я бы пошел еще дальше и сохранил его в constants.js файле для лучшей согласованности. Я отредактирую свой код, спасибо!

3. Этот ответ должен быть помечен как принятый ответ.

4. Почему это clearInterval(interval) важно? Разве это не отменит установленный вами интервал?

5. @Kid_Learning_C Чтобы интервал не выполнялся, когда компонент исчез.

Ответ №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);
 

Ответ №3:

вы также делаете это с помощью 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>;
 

};

Ответ №4:

 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>;
};