TypeError:当组件在 React 中上传文件时,无法读取未定义的属性“map”
React 新手在这里。 当 props.submitClk === true(绿灯表示我的上传按钮已被点击,并且文件已从另一个组件的表单发送)时,我尝试使用新技术对象更新状态 setList,但目前只是“SomeObject”。点击后,我收到“TypeError 无法读取未定义的属性‘map’”。我尝试摆弄一些条件,但经过几个小时的尝试后没有运气。这是一个异步问题,并且映射发生得太快了吗?当我删除对象时,handleRemove 工作正常。如果我删除 if 语句下的函数,它不会在表单提交时抛出错误。此外,对象将变得更大,这就是它目前以这种方式嵌套的原因。感谢您的回答。
function SampleData(props) {
const [list, setList] = React.useState( [
{
closedguard: [
{
name: "Armbar",
link: "",
x: "X",
id: "1",
},
{
name: "Triangle",
link: "",
x: "X",
id: "2",
},
{
name: "Omaplata",
link: "",
x: "X",
id: "3",
},
] }
] );
if( props.submitClk === true) {
setList([...list, 'SomeObject'])
}
const handleRemove = (id) => {
const newList = list[0].closedguard.filter(move => move.id !== id);
setList([{ closedguard: newList }]);
};
return (
<div className="guard">
<ul className="techUl">
{" "}
Closed Guard
{list.map((pos) =>
pos.closedguard.map((move, id) => (
<li
key={id}
className="techLi"
>{move.name}
<span onClick={(id) => handleRemove(move.id)}> {move.x}</span>
</li>
))
)}
</ul>
</div>
);
}
首先,如果没有
someObject
,您将面临
过多的重新渲染。React 会限制渲染次数以防止无限循环。
然后,您正在更新嵌套对象:
[
{
closedguard: [
{
name: "Armbar",
link: "",
x: "X",
id: "1",
},
{
name: "Triangle",
link: "",
x: "X",
id: "2",
},
{
name: "Omaplata",
link: "",
x: "X",
id: "3",
},
]
}
]
对象数组,然后对象
closedguard
位于其中,它是一个数组。
因此,您可以在条件内执行的操作是
// think is the some objects
const newObject = [
{
name: "test1",
link: "",
x: "X",
id: "5"
},
{
name: "test2",
link: "",
x: "X",
id: "56"
}
];
setList([{ closedguard: [...list[0].closedguard, ...newObject] }]);
而不是
setList([...list, 'SomeObject'])
要更新您的状态
list
的 closeguard 数组,您可以查看 @Nafis 的回答,但您应该使用 useEffect 钩子来运行副作用。尝试将此逻辑与 @Nafis 的回答结合起来以更新状态 -
if( props.submitClk === true) { setList([...list, 'SomeObject'])
在 useEffect 钩子内,如下所示
useEffect(()=>{
if( props.submitClk === true) {
setList([...list, 'SomeObject']) }
},[list])
现在修改 list.map 函数如下,那么您将不会收到 map 未定义错误
{list.length > 0 && list.map((pos) =>
pos.closedguard.map((move, id) => (
<li
key={id}
className="techLi"
>{move.name}
<span onClick={(id) => handleRemove(move.id)}> {move.x}</span>
</li>
))
)}
让我知道它是否有效
如果您想更新嵌套对象以将元素添加到
closedguard:
属性数组,请检查@Nafis 的回答。
我认为问题在于您添加的新对象没有
closedguard
属性,因此 map 函数无法映射该对象。
如果添加具有该属性的对象,它将起作用,例如:
const objToAdd = {closedguard: [
{
name: "newObj1",
link: "",
x: "X",
id: "3",
},
{
name: "newObj2",
link: "",
x: "X",
id: "3",
}]
}
如果您正在添加具有另一个属性的对象,则可能需要映射的是相应的键,以确保您从对象中获取属性,因此需要更改
pos.closedguard.map((move, id) => (
通过:
pos[Object.keys(pos)[0]].map((move, id) => (
例如。
所以在如果您的对象没有
closedguard
,则该对象的第一个属性将被映射。
发布我提案的完整回报只是为了让我的提案清晰:
return (
<div className="guard">
<ul className="techUl">
{" "}
Closed Guard
{list.map((pos) =>
pos[Object.keys(pos)[0]].map((move, id) => ( //CHANGE HERE
<li
key={id} className="techLi"
>{move.name}
<span onClick={(id) => handleRemove(move.id)}> {move.x}</span>
</li>
))
)}
</ul>
<button onClick={handleOnClick}>Button</button>
</div>
);