Reactjs useState未在React中设置

Reactjs useState未在React中设置,reactjs,react-hooks,Reactjs,React Hooks,我试图让useState在用户单击向上或向下箭头时工作,但由于某些原因,该状态未被更新 即使我设置Timeout以查看索引是否得到更新,仍然没有更新。我完全被这搞糊涂了 import React, { useEffect, useState } from 'react'; const Wrapper = ({ children }) => { const [index, setIndex] = useState(-1); useEffect(() => { doc

我试图让useState在用户单击向上或向下箭头时工作,但由于某些原因,该状态未被更新

即使我设置Timeout以查看索引是否得到更新,仍然没有更新。我完全被这搞糊涂了

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

const Wrapper = ({ children }) => {
  const [index, setIndex] = useState(-1);

  useEffect(() => {
    document.addEventListener('keydown', handler);
    return () => {
      document.removeEventListener('keydown', handler);
    };
  }, []);

  const handler = (event) => {
    if (event.key === 'ArrowDown') {
      setIndex(index + 1);
      console.log('index = ', index);
    }
  };

  return (
    <div>
      {children}
    </div>
  );
};

export default Wrapper;
import React,{useffect,useState}来自“React”;
常量包装器=({children})=>{
const[index,setIndex]=useState(-1);
useffect(()=>{
文件。addEventListener('keydown',handler);
return()=>{
document.removeEventListener('keydown',handler);
};
}, []);
常量处理程序=(事件)=>{
如果(event.key==='ArrowDown'){
setIndex(index+1);
log('index=',index);
}
};
返回(
{儿童}
);
};
导出默认包装器;

由于
设置状态的异步性质,您应该记录以前的状态

setIndex(prev=>{
console.log(“prev=”,prev);
返回prev+1;
});

提示位于
常量[索引…
-它永远不会更改。请使用
设置状态的函数形式

const handler = (event) => {
  if (event.key === 'ArrowDown') {
    setIndex(oldIndex => oldIndex + 1)
  }
}
这是因为第一次渲染期间的
索引将是
-1
,即使在
句柄
函数内部的闭包中也不会更改。在新渲染期间,将创建一个具有不同常量
索引
的新
句柄
函数,但该函数将被忽略,因为
useffect(fn,[])
第二个参数确保仅在第一次渲染期间执行
fn


有关更多详细信息,请参阅。

状态更新是异步的。控制台日志将始终为您提供旧状态。您的可能副本应移动
处理程序
useffect
@JohnRuddell中,与异步无关。即使渲染是同步的,也会出现相同的问题,但
处理程序
的关闭来自第一次渲染仅由于
useffect
ok的第二个参数,存在多个问题:由于
setState
的异步性质,
index
常量不会在1次渲染中更新(仅影响
控制台.log
)+由于仅在第一次渲染期间执行
useffect
,因此
index
是第一次渲染的闭包(影响为什么
index
在任何非第一次渲染中最多为0,因为
-1+1
为0)在useEffect闭包之外,是否还有其他方法可以获取current的值?闭包可以想象为来自超市的账单,如果有一天你买了一杯牛奶,第二天买了一个橘子,那么第一天账单上会有什么?默认情况下,上一次渲染会丢失所有内容,只有当前道具和状态可用,并且只有savi可以使用ng旧值可以访问(在您的情况下,从第一次渲染传递到addEventListener的句柄函数),但我认为我正在将值保存在索引中?我如何将任何内容保存在句柄函数中?很抱歉,没有理解您所说的。从某种意义上说,我试图解释,
index
的值已“保存”在
处理程序
函数中…但两者都是在另一个函数(
包装器
)中创建的
常量,因此每次执行
包装器
函数(=在每次渲染中),它们是完全不同的常数,具有独立的值。请随意提问一个更完整的问题,作为单独的stackoverflow问题。我不明白您在简短的评论中想问什么:(