我试图使用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)
}))}
答案 0 :(得分: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"));
答案 1 :(得分:0)
如果您的列表为空,则只需检查列表是否为空即可解决此问题:
{if(state.list){
state.list.map((data,id)=>{
console.log ('loop data',data)
})
}}