#javascript #reactjs #react-hooks #state
Вопрос:
Я использую reactjs в своем приложении . Изначально currid_s имеет значение -1.. позже после нажатия кнопки он устанавливается на 2, но таймер не показывает обновленное значение в консоли. Почему? Вот код
import React, { useState, useEffect } from "react";
export default function App() {
const [currid_s, setcurrid_s] = React.useState(-1);
const handless = () => {
console.log("yess");
setcurrid_s(2);
};
useEffect(() => {
console.log(currid_s, "yes");
getPosts();
const interval = setInterval(() => {
getPosts();
}, 2000);
return () => clearInterval(interval);
}, []);
// const all_pooo=()=>{
// console.log(curr,"dddd")
// }
const getPosts = async () => {
console.log(currid_s);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={handless}>gggg</button>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Вот ссылка на песочницу кода
https://codesandbox.io/embed/beautiful-ardinghelli-dg1r4?file=/src/App.jsamp;codemirror=1
Комментарии:
1. Функция обратного вызова интервала имеет замыкание по значению
currid_s
, которое действовало при установке интервала таймера. Вам нужно устанавливать новый интервал приcurrid_s
каждом обновлении. Вы можете сделать это, добавивcurrid_s
в массив зависимостейuseEffect
крючок.2. @Yousaf, но как интервал влияет на значение currid_s?
3. Можете ли вы изменить код и поле @Yousaf, пожалуйста?
4. ДЕМОНСТРАЦИЯ
5. @Тушаршахи, что ты имеешь в виду?
setInterval
не изменяет свое значение; он просто вызывает функцию,getPosts
т. Е. регистрирует значениеcurrid_s
.
Ответ №1:
Вы не можете получить новое значение состояния внутри setInterval
, потому что вы храните старую версию getPosts
внутри функции обратного вызова интервала.
Что происходит, так это при currid_s
обновлении, повторной отправке компонента приложения и инициализации новой getPosts
функции, содержащей новое значение. Однако setInterval
функция обратного вызова сохраняет ссылку на старую getPosts
функцию, содержащую старое значение. Эта старая getPosts
функция будет печатать копию старого currid_s
значения, которое было присвоено при монтаже компонента приложения. Javascript не поддерживает ссылки на примитивы, поэтому ваша старая getPosts
функция не имеет нового значения.
Если вы хотите печатать свои currid_s
обновления всякий раз, когда они обновляются, просто сделайте это:
useEffect(() => {
console.log(currid_s)
}, [currid_s])
Комментарии:
1. У меня на сайте много крючков для реакции. Должен ли я добавить все это в зависимость?
Ответ №2:
Вы можете изменить currid_s
значение с a useState()
на a useRef()
, чтобы его значение было доступно из закрытия, которое setInterval
фиксирует обратный вызов:
const { useRef, useEffect } = React;
function App() {
const currid_s = useRef(-1);
const handless = () => {
currid_s.current = 2;
};
useEffect(() => {
const getPosts = () => {
console.log(currid_s.current);
};
getPosts();
const interval = setInterval(() => {
getPosts();
}, 2000);
return () => {
clearInterval(interval);
};
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={handless}>Click me</button>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>