Reactjs react const在使用useImmer设置状态后包含未定义

Reactjs react const在使用useImmer设置状态后包含未定义,reactjs,react-hooks,Reactjs,React Hooks,我正在尝试将我的propsValue移动到新数组中 我的代码中有两个按钮,第一个按钮(转换它们)执行传输。 第二个按钮(全部打印)打印用户的每个键和值 但是,我的“全部打印”按钮在传输后打印未定义 我应该如何修改代码以包含正确的值 多谢各位 import React from 'react'; import { useImmer } from "use-immer"; const UserImmer = () => { const propsValue = [

我正在尝试将我的propsValue移动到新数组中

我的代码中有两个按钮,第一个按钮(转换它们)执行传输。 第二个按钮(全部打印)打印用户的每个键和值

但是,我的“全部打印”按钮在传输后打印未定义

我应该如何修改代码以包含正确的值

多谢各位

import React from 'react';
import { useImmer } from "use-immer";
const UserImmer = () => {
  const propsValue = [
    {
      value: "Name", key:"first_name"
    },
    {
      value: "last Name", key:"last_name"
    },
    {
      value: "E mail", key:"e_mail"
    },
    {
      value: "Address", key: "address"
    }
  ]

  const [user, setUser] = useImmer({
    value: '',
    key: '',
  })
  const [users, setUsers] = useImmer([])

  const onbuttonChange = () => {
    //iteration begins
    const name = "HAHA2";
    propsValue.map(data =>  (
       
       console.log("Iteration : ", data.value, " : ", data.key),
       
       //save propsValue into user one by one
       setUser(draft => {
            draft.value =  data.value;
            draft.key = data.key;
          }),

          //push user into Users
          //
          setUsers(draft => {
            draft.push(user);
          }),

          //initialize the user
        setUser(draft => {
            draft.value = "";
            draft.key = "";
        })
    ))
  }
  const onClickUser = () => {
    //prints final result of Users but it prtins four undefined
    users.map(temp => console.log("THe Users: ", temp.value, " : " , temp.key));
  }
  return (
    <div>
      
      <button onClick={onClickUser}>print All</button>
      <button onClick={onbuttonChange}>Convert them</button>
    </div>
  )
}
export default UserImmer;

从“React”导入React;
从“使用immer”导入{useImmer};
常量UserImmer=()=>{
常量属性值=[
{
值:“名称”,键:“名字”
},
{
值:“姓氏”,键:“姓氏”
},
{
值:“电子邮件”,键:“电子邮件”
},
{
值:“地址”,键:“地址”
}
]
const[user,setUser]=useImmer({
值:“”,
键:“”,
})
const[users,setUsers]=useImmer([]
const onbuttonChange=()=>{
//迭代开始
const name=“HAHA2”;
propsValue.map(数据=>(
log(“迭代:”,data.value,“:”,data.key),
//将propsValue逐个保存到用户中
setUser(草稿=>{
draft.value=data.value;
draft.key=data.key;
}),
//将用户推入用户
//
设置用户(草稿=>{
推送(用户);
}),
//初始化用户
setUser(草稿=>{
draft.value=“”;
draft.key=“”;
})
))
}
const onClickUser=()=>{
//打印用户的最终结果,但其中有四个未定义
map(temp=>console.log(“用户:”,temp.value,“:”,temp.key));
}
返回(
全部打印
转化他们
)
}
导出默认用户界面;

这有多方面的问题

第一。其
未定义的原因是您试图显示它没有的数据。您希望在
控制台.log(“用户:”,temp.name,“:”,temp.key))
中通过
temp.name
显示属性
name
,但查看对象结构-它没有属性
name
。它有
。所以这是第一个问题

第二。钩子中的变量
user
,在所有
映射之后更新并重新呈现。也就是说,在
映射
的整个时间内,
用户
始终保持默认的
用户
数据为空。当数据更改后需要重新呈现组件时,应使用挂钩。因此,我们应该只创建一个变量,而不是使用钩子

let user = {
  value: "",
  key: ""
};
而不是
setUser

(user = data),
如果您愿意,它将以最简单的方式从
value
更改为
name

(user = {
  name: data.value,
  key: data.key
}),
或者更好-删除用户!这没有用。数据是一样的。它没有额外的功能,而是占用资源

三,。推不动

    setUsers((draft) => {
      draft.push(user);
    })
您可以将其更改为
users.push(user)
,但是
users
也不能是钩子。因此,当它更改时,将不会重新渲染组件。在您的情况下,这很好,因为数据仅在再次单击按钮后显示。但是,如果您希望在不单击“打印”按钮的情况下显示数据,但在向其中添加数据时要尽快显示,则需要使用钩子,以便重新渲染。为此,创建一个新数组来存储所有“用户”,并在
map
末尾通过传递数组运行
setUsers
。这样组件就不必多次重新渲染

另外,
map
应该返回一些内容。在您的例子中,
propsValue.map
不返回任何内容。我通过修复以下三件事重新编写了您的代码:。它按你的意思工作


注意:这也可以在不使用
使用immer
的情况下实现。一个简单的反应
useState
在您的情况下也会这样做。

谢谢您的提示。修改了temp.name-->temp.values,但它仍然不会在我的screen@JinPark我更新了我的帖子。我描述了其他问题以及如何解决它们。希望如此helps@JinPark如果在某些情况下,我没有理解您的目标,例如与
用户
,或者如果您不理解我的解释,请随意推荐。我会尽力回答。哇,太棒了,这是我在stackoverflow收到的最棒的建议。非常感谢你的建议谢谢