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