Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用React-useState钩子向循环内的对象添加键值对_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 使用React-useState钩子向循环内的对象添加键值对

Javascript 使用React-useState钩子向循环内的对象添加键值对,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在尝试使用useStateinsidemap函数向对象添加键值对。但是,setContainer({…container[data.pk]:data.name})中的扩展操作似乎无效 下面的代码片段正好说明了我试图解决的问题。事实上,在我的原始代码中,容器在另一个ContextProvider组件中声明,并使用useContext引用,但为了简单起见,我将其替换为useState 我想这与setStatehook的异步特性有关,但我不完全理解引擎盖下到底发生了什么 请让我知道是什么导致了这个

我正在尝试使用
useState
inside
map
函数向对象添加键值对。但是,
setContainer({…container[data.pk]:data.name})中的扩展操作似乎无效

下面的代码片段正好说明了我试图解决的问题。事实上,在我的原始代码中,
容器
在另一个ContextProvider组件中声明,并使用
useContext
引用,但为了简单起见,我将其替换为
useState

我想这与
setState
hook的异步特性有关,但我不完全理解引擎盖下到底发生了什么

请让我知道是什么导致了这个问题,以及如何产生我预期的结果。 多谢各位

const{useState,useffect}=React;
const myData=[{pk:1,名称:'apple'},
{pk:2,名称:'banana'},
{pk:3,名称:'citrus'},
]
常量示例=()=>{
const[container,setContainer]=useState({});
useffect(()=>{
myData.map(数据=>{
log(`在此迭代过程中,应将键值对(key${data.pk}和value'${data.name}')添加到容器`);
setContainer({…container[data.pk]:data.name});
})
}, [])
返回(
我期望的结果:{{'1':'apple','2':'banana','3':'citruss'}}
结果:{JSON.stringify(容器)}
);
};
//渲染它
ReactDOM.render(
,
document.getElementById(“react”)
);

你说得对,这是因为
setState
hook的异步特性,它基本上是成批运行的

发件人:

setState()不会立即改变this.state,但会创建挂起的状态转换。调用此方法后访问this.state可能会返回现有值。无法保证对setState调用的同步操作,并且可能会对调用进行批处理以提高性能

可以先创建对象,然后在循环完成后进行设置。你也不应该在这里使用。因为您没有创建新数组

useffect(()=>{
常量dataObj={};
myData.forEach(数据=>{
dataObj[data.pk]=data.name;
});
setContainer(dataObj);

}, []);以下是您的组件中逐步发生的情况

  • container
    setContainer
    使用
    useState
    钩子进行初始化
  • 映射到
    myData
    的效果已被注册,而且由于作为第二个参数传递的是空数组
    []
    ,因此它在组件的整个生命周期中将只运行一次
  • 您在效果中注册的回调将运行。如果您对容器以及键值对进行控制台.log'd,则会出现这种情况
  • (键1值“苹果”);容器{}
    (键2值“香蕉”);容器{}
    (关键3值“柑橘”);容器{}
    
    等等,容器不应该在每次迭代时更新吗

    嗯,是的,但不是以你期望的方式。
    useffect
    中引用的
    容器
    myData.map
    的每次迭代中保留其原始的
    {}
    值。那么实际上发生的是

    setContainer({…{},1:'apple'})//重新加载
    setContainer({…{},2:'banana'})//重新加载
    setContainer({…{},3:'citrus'})//重新加载
    
    citrus
    是最后一次重播后的最终显示

    这里有一个方法可以让你达到你想要的结果

    const{useState,useffect}=React;
    const myData=[{pk:1,名称:'apple'},
    {pk:2,名称:'banana'},
    {pk:3,名称:'citrus'},
    ]
    常量示例=()=>{
    const[container,setContainer]=useState({});
    useffect(()=>{
    setContainer(myData.reduce((obj,data)=>({…obj[data.pk]:data.name}),{}))
    }, [])
    返回(
    我期望的结果:{{'1':'apple','2':'banana','3':'citruss'}}
    结果:{JSON.stringify(容器)}
    );
    };
    //渲染它
    ReactDOM.render(
    ,
    document.getElementById(“react”)
    );
    
    将setstate中的逻辑从中取出,并使用新对象仅调用setstate一次。