React. Обновить значение внутри setInterval по внешней переменной
Задачка поначалу показалась весьма простой, но когда начал работать с таймером - что-то пошло не так. К примеру:
const [number, setNumber] = useState(4);
useEffect(() => {
setInterval(out, 1500);
}, []);
const out = () => {
console.log(number);
};
В общем нужно, чтобы при смене number в консоль выводилось новое значение, а то у меня постоянно выводится 4. Пробовал делать clearInterval и создавать новый таймер при изменении того же number, но, в итоге, у меня существовало 2 таймера. Подскажите как оптимально решить задачку.
Ответы (1 шт):
Можно например так:
import React from "react";
const Timer = () => {
const [number, setNumber] = React.useState(1);
React.useEffect(() => {
// таймер пересоздаётся каждый раз когда обновляется number
const id = setInterval(() => setNumber(number + 1), 1000);
return () => {
clearInterval(id);
};
}, [number]);
return <div>Number is {number}</div>;
};
export default Timer;
Но даже проще можно написать так:
import React from "react";
const Timer = () => {
const [number, setNumber] = React.useState(1);
React.useEffect(() => {
setTimeout(() => setNumber(number + 1), 1000);
}, [number]);
return <div>Number is {number}</div>;
};
export default Timer;
Потому что в первом варианте из-за особенностей реакта каждый раз пересоздаётся таймер. С одним таймером не будет ре-рендерится обновлённое значение (если оно должно быть не только в консоли):
import React from "react";
const Timer = () => {
const [number, setNumber] = React.useState(1);
let n = 0;
React.useEffect(() => {
// таймер создаётся 1 раз
const id = setInterval(() => {
console.log(n++);
}, 1000);
return () => {
clearInterval(id);
};
}, []);
return (
<>
<div>Number is {number}</div>
<div>n is {n}</div>
</>
);
};
export default Timer;
Последний вариант - это не Реакт стиль -> bad practice