【问题标题】:How to use map function for hooks useState properties如何将地图函数用于钩子 useState 属性
【发布时间】:2019-08-01 08:53:16
【问题描述】:

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

//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)
}))}

【问题讨论】:

  • 你是如何将state 变量放在map 之上的?
  • 按原样,您的代码应该可以工作。因此,正如@Treycos 怀疑的那样,您可能以错误的方式设置状态,因此您丢失了list 并得到了错误。请分享您组件的其他部分。
  • 好的,但它会是一个完整的组件,可以吗?
  • 没问题。当然,如果您愿意,您可以跳过不相关的部分。我们只需要知道你在哪里以及如何设置你的状态。
  • 我刚刚清除了错误,但仍然对方法不满意。为什么我不能在钩子中执行相同的代码?现在我必须使用三元运算符来检查它是否为空。 {(state.list) ? <code> {(state.list.map((data,id)=>{.....}))}</code>:null}

标签: reactjs react-hooks


【解决方案1】:

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

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

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

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

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

你取旧状态,通过spreading它保留其他属性,然后更新相关部分。我会在这里使用event 而不是name。这不是“名称”,实际上它毕竟是“事件”:)

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

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

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

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

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

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

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

此外,您不需要在不需要时绑定函数。您可以在下面找到代码的工作副本。我只是删除了不必要的部分并修复了问题。

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"));

【讨论】:

    【解决方案2】:

    如果您的列表为空,您将收到此错误,只需检查列表是否为空即可解决问题:

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

    【讨论】:

    • 不能同意你的观点,因为对于Array.map,空数组是完全有效的。 Boolean([]) =&gt; TRUE.
    • 是的,根据逻辑,最初数组必须​​为空。该代码在普通类组件中工作正常。当我转换成 React-Hooks 时,我遇到了这个错误。帮我解决这个问题。
    • @Little_Programmer 检查此代码框,您的代码正在运行:codesandbox.io/s/prod-microservice-u7oqh
    • 是的,我检查了它,但它仍然反映了我的 IDE 中的错误。 :(
    猜你喜欢
    • 2020-06-27
    • 2021-10-12
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2021-07-27
    • 2022-10-12
    相关资源
    最近更新 更多