如何将 map 函数用于钩子 useState 属性 [英] How to use map function for hooks useState properties

查看:162
本文介绍了如何将 map 函数用于钩子 useState 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 map 函数在 react-hooks useState 中循环我的列表数据,但我遇到了TypeError:无法读取未定义的属性‘map’"的错误

//1.初始声明const App = props=>{const [state, changeState]= useState ({名称:"",事件标题:"",细节:"",对象数据:{},列表:[],切换索引:"",编辑名称:"",编辑事件标题:"",编辑详情:"",编辑对象:{}});//2.逻辑来了//3.尝试使用地图{(state.list.map((data,id)=>{console.log('循环数据',数据)}))}

解决方案

因为我们怀疑您没有以正确的方式设置您的状态.我试图在我的评论中解释,当您设置状态时,使用钩子不会将更新的属性与当前的属性合并.所以,你应该考虑一下.现在你正在像这样设置你的状态:

const handleName = name =>{更改状态({名称:名称.目标.值});};

在这里,您正在设置 name 属性并丢失状态的其他部分.因此,当您设置状态时,您将丢失 list 以及状态的其他部分.你应该这样做:

const handleName = name =>{const { 目标 } = 名称;更改状态(状态 =>({...状态,名称:目标值,}));};

您采用旧状态,通过 传播它,然后更新相关部分.我会在这里使用 event 而不是 name.这不是名称",实际上毕竟是事件":)

const handleName = event =>{const { 目标} = 事件;更改状态(状态 =>({...状态,名称:目标值,}));};

此外,您的代码中还有一些其他问题和不必要的部分.例如,您在处理提交和向 list 中添加对象时费力不讨好.您不需要额外的 objdata 在您的状态中将其推送到 list.如果你想构造一个额外的对象,你可以在函数本身中完成.

这是一个非常简单的方法:

const submitHandle = () =>{const { name, eventTitle, details } = state;const obj = { 名称,事件标题,详细信息};更改状态(状态 =>({...状态,列表: [ ...state.list, obj ],}))};

同样,我们使用扩展运算符来保留状态的其他部分,同时更新 list 以保留其他对象.不要像在 submitHandle 函数中那样设置状态.试着把它想得简单:)

另外,在不必要的时候,你不需要绑定你的函数.您可以在下面找到代码的工作副本.我只是删除了不必要的部分并解决了问题.

import React, { useState } from "react";从react-dom"导入 ReactDOM;const App = 道具 =>{const [状态,更改状态] = useState({名称: "",事件标题:",细节: "",列表: [],切换索引:"",编辑名称:"",编辑事件标题:"",编辑详情:"",编辑对象:{}});const handleName = 事件 =>{const { 目标} = 事件;更改状态(状态 =>({...状态,名称:target.value}));};const handleEventTitle = 事件 =>{const { 目标 } = 事件;更改状态(状态 =>({...状态,事件标题:target.value}));};const handleDetails = 事件 =>{const { 目标 } = 事件;更改状态(状态 =>({...状态,详细信息:target.value}));};const submitHandle = () =>{const { name, eventTitle, details } = state;const obj = { 名称,事件标题,详细信息};更改状态(状态 =>({...状态,列表:[...state.list, obj]}));};const resetHandle = () =>更改状态(状态 =>({...状态,名称: "",事件标题:",细节: ""}));返回 (<div><div className="jumbotron jumbotron-fluid"><div className="容器"><h1 className="display-5 text-center">让我们设置您的提醒</h1>

<div className="bg-dark container-fluid"><div className="row"><div className="col-sm-12 col-md-4 col-lg-4 "/><div className="col-sm-12 col-md-4 col-lg-4 "><div className="card login-card"><div className="卡片头"><h3 className="text-center">待办事项清单表格</h3>

<div className="card-body"><form className="form-elements"><输入值={state.name}className="表单控件表单输入表单元素"类型=文本"onChange={句柄名称}占位符=用户名"/><输入值={state.eventTitle}className="表单控件表单输入表单元素"类型=文本"onChange={handleEventTitle}占位符=事件标题"/><输入值={state.details}className="表单控件表单输入表单元素"类型=文本"onChange={handleDetails}占位符=详细信息"/></表单>

<div className="card-footer "><按钮类型=提交"onClick={submitHandle}className="btn-primary offset-lg-1 offset-md-0 btn-sm ">创造<按钮类型=重置"onClick={resetHandle}className="btn-primary offset-lg-5 offset-md-0 btn-sm">取消

<div className="col-sm-12 col-md-4 col-lg-4 "/>

<div className="container-fluid bg-dark"><div className="行">{state.list.map(data => (<div style={{ border: "1px black solid" }}><p>{data.name}</p><p>{data.eventTitle}</p><p>{data.details}</p>

))}

);};ReactDOM.render(, document.getElementById("root"));

I tried to use map function for looping my list data in react-hooks useState but I stuck with an error that "TypeError: Cannot read property 'map' of undefined"

//1.Initial declaration
const App = props=>  {
const [state, changeState]= useState ({
    name:"",
    eventTitle:"",
    details:"",
    objdata:{},
    list:[],
    toggleIndex:"",
    editName: "",
    editEventTitle: "",
    editDetails: "",
    editObj: {}
});


//2.logic comes here


//3.tried using map


{(state.list.map((data,id)=>{
console.log ('loop data',data)
}))}

解决方案

As we suspected you are not setting your state in the right way. I tried to explain in my comment, with hooks when you set your state it does not merge the updated properties with the current one. So, you should think about that. Right now you are setting your state like that:

const handleName = name => {
  changeState({
    name: name.target.value
  });
};

Here, you are setting the name property and lose other parts of your state. Hence, when you set your state, you lose list as well as other parts of your state. This is how you should do it:

const handleName = name => {
  const { target } = name;

  changeState(state => ({
    ...state,
    name: target.value,
  }));
};

You take the old state, keep the other properties by spreading it, then update the relevant part. I would use here event instead of name. It is not "name", it is "event" after all actually :)

const handleName = event => {
  const { target } = event;

  changeState(state => ({
    ...state,
    name: target.value,
  }));
};

Also, you have a few other problems and unnecessary parts in your code. For example, you are struggling too much to handle the submit and add an object to your list. You don't need an extra objdata in your state to push it to the list. If you want to construct an extra object, you can do it in the function itself.

Here is a very simple way to do it:

const submitHandle = () => {
  const { name, eventTitle, details } = state;
  const obj = { name, eventTitle, details };

  changeState(state => ({
    ...state,
    list: [ ...state.list, obj ],
  }))
};

Again, we are using spread operator to keep both the other parts of the state and while updating the list, to keep other objects. Do not set your state as you do in your submitHandle function. Try to think it simple :)

Also, you don't need to bind your functions when it is not necessary. You can find a working copy of the code below. I just removed unnecessary parts and fix the issues.

import React, { useState } from "react";
import ReactDOM from "react-dom";

const App = props => {
  const [state, changeState] = useState({
    name: "",
    eventTitle: "",
    details: "",
    list: [],
    toggleIndex: "",
    editName: "",
    editEventTitle: "",
    editDetails: "",
    editObj: {}
  });

  const handleName = event => {
    const { target } = event;

    changeState(state => ({
      ...state,
      name: target.value
    }));
  };

  const handleEventTitle = event => {
    const { target } = event;

    changeState(state => ({
      ...state,
      eventTitle: target.value
    }));
  };

  const handleDetails = event => {
    const { target } = event;

    changeState(state => ({
      ...state,
      details: target.value
    }));
  };

  const submitHandle = () => {
    const { name, eventTitle, details } = state;
    const obj = { name, eventTitle, details };

    changeState(state => ({
      ...state,
      list: [...state.list, obj]
    }));
  };

  const resetHandle = () =>
    changeState(state => ({
      ...state,
      name: "",
      eventTitle: "",
      details: ""
    }));

  return (
    <div>
      <div className="jumbotron jumbotron-fluid">
        <div className="container">
          <h1 className="display-5 text-center">Let's set your reminders</h1>
        </div>
      </div>
      <div className="bg-dark container-fluid">
        <div className="row">
          <div className="col-sm-12 col-md-4 col-lg-4 " />

          <div className="col-sm-12 col-md-4 col-lg-4 ">
            <div className="card login-card ">
              <div className=" card-header ">
                <h3 className="text-center"> TO-DO LIST FORM</h3>
              </div>

              <div className="card-body">
                <form className="form-elements">
                  <input
                    value={state.name}
                    className="form-control form-inputs form-elements"
                    type="text"
                    onChange={handleName}
                    placeholder="user name"
                  />
                  <input
                    value={state.eventTitle}
                    className="form-control form-inputs form-elements"
                    type="text"
                    onChange={handleEventTitle}
                    placeholder="Event Title"
                  />
                  <input
                    value={state.details}
                    className="form-control form-inputs form-elements"
                    type="text"
                    onChange={handleDetails}
                    placeholder="Details "
                  />
                </form>
              </div>

              <div className="card-footer ">
                <button
                  type="submit"
                  onClick={submitHandle}
                  className="btn-primary offset-lg-1 offset-md-0 btn-sm "
                >
                  Create
                </button>

                <button
                  type="reset"
                  onClick={resetHandle}
                  className="btn-primary offset-lg-5 offset-md-0 btn-sm"
                >
                  cancel
                </button>
              </div>
            </div>
          </div>
          <div className="col-sm-12 col-md-4 col-lg-4 " />
        </div>

        <div className="container-fluid bg-dark">
          <div className="row ">
            {state.list.map(data => (
              <div style={{ border: "1px black solid" }}>
                <p>{data.name}</p>
                <p>{data.eventTitle}</p>
                <p>{data.details}</p>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div
        className="footer footer-copyright"
        style={{ background: "#e9ecef" }}
      >
        <div className="container">
          <h6 className=" text-center">Just make it work ;)</h6>
        </div>
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));

这篇关于如何将 map 函数用于钩子 useState 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆