我正在将数据从 Node JS 发送到数组对象中的 React JS。在 React JS 中,当我设置响应数据时,我收到错误“对象作为 React 子对象无效(找到:对象带有键 {eventName、eventDate、merchantid})。如果您打算呈现子集合,请使用数组相反。”
我查看了 Stackoverflow 的一篇帖子 useState Array of Objects。我也以同样的方式设置值,但出现错误。
下面是我从 Node JS 发送的数据。
[
{
eventName: 'Sankranti',
eventDate: 2021-01-21T00:00:00.000Z,
merchantid: 'tp012345'
},
{
eventName: 'Sankranti 1',
eventDate: 2021-01-26T00:00:00.000Z,
merchantid: 'tp012345'
}
]
在我的代码下方,我在 setEventList(eventList => [...eventList, response]) 处遇到错误。根据我在代码下面添加的评论。
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import Carousel from 'react-bootstrap/Carousel'
import axios from 'axios';
import DashboardNavBar from './DashboardNavBar';
import Header from './Header';
const DashboardPage = (props) => {
const [eventList, setEventList] = useState([])
const [index, setIndex] = useState()
if (!props.profileData) {
useEffect(() => {
(async () => {
const eventsList = await axios.get(
"http://localhost:3000/api/dashboard"
);
console.log(eventsList.data)
const response = eventsList.data
setEventList(eventList => [...eventList, response])
if(!response){
setErrorMsg('Please create Event and then add User !!')
}
})();
}, []);
}
const eventListRender = eventList.length > 0 ?
eventList.map((item,index) => {
console.log('item name: ', item[index].eventName)
return <Carousel.Item>{item[index].eventName}</Carousel.Item>
}) :
<Carousel.Item>No upcoming events</Carousel.Item>
const handleSelect = (selectedIndex) => {
console.log(eventList)
console.log(selectedIndex)
setIndex(selectedIndex)
}
return (
<div>
<DashboardNavBar />
<Header />
<p >Welcome !!!!!!</p>
<Carousel
activeIndex={index}
onSelect={handleSelect}
>
{eventListRender}
</Carousel>
</div>
);
}
const mapStateToProps = (state) => ({
profileData: state.auth.profileData
})
export default connect(mapStateToProps) (DashboardPage);
添加下面的代码后,它总是读取第一次出现
const eventListRender = eventList.length > 0 ?
eventList.map((item,index) => {
console.log('item name: ', item[index].eventName)
return <Carousel.Item>{item[index].eventName}</Carousel.Item>
}) :
<Carousel.Item>No upcoming events</Carousel.Item>
请查找更新的结果
答案 0 :(得分:1)
好的,你的代码和盒子证实了我的怀疑。在您的沙箱中,您已将模拟响应作为平面数组直接放置在您的状态中
const [eventList, setEventList] = useState([
{
eventName: "Sankranti",
eventDate: "2021-01-21T00:00:00.000Z",
merchantid: "tp012345"
},
{
eventName: "Sankranti 1",
eventDate: "2021-01-26T00:00:00.000Z",
merchantid: "tp012345"
}
]);
这允许渲染按预期工作,只需映射这个平面对象数组。
eventList.map((item, index) => {
return <Carousel.Item>{item.eventName}</Carousel.Item>;
})
但是在您的原始代码中,您没有将状态更新为平面数组。 response
是 一个数组,即 [object1, object2]
并且您将此数组附加到您所在州的 eventList
数组的末尾。>
setEventList(eventList => [...eventList, response])
这会将您的状态更新为类似 [[object1, object2]]
的内容,因此您使用的映射函数仅映射一个元素。
eventList.map((item, index) => {
return <Carousel.Item>{item[index].eventName}</Carousel.Item>;
})
原因是因为您使用了外层的数组索引(回忆一下eventList
是一个长度为1的数组)来访问内层嵌套数组(长度为 2 的数组)。在迭代外部数组时,index
仅达到值 0
,因此仅呈现内部数组的第零个元素。
在此代码中查看更准确的问题重现:
const response = [
{
eventName: "Sankranti",
eventDate: "2021-01-21T00:00:00.000Z",
merchantid: "tp012345"
},
{
eventName: "Sankranti 1",
eventDate: "2021-01-26T00:00:00.000Z",
merchantid: "tp012345"
}
];
function App() {
const [eventList, setEventList] = useState([]);
useEffect(() => {
setEventList((eventList) => [...eventList, response]);
}, []);
const eventListRender =
eventList.length > 0 ? (
eventList.map((item, index) => {
return <Carousel.Item>{item[index].eventName}</Carousel.Item>;
})
) : (
<Carousel.Item>No upcoming events</Carousel.Item>
);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Carousel>{eventListRender}</Carousel>
</div>
);
}
如果响应数据也是一个数组,那么您似乎应该将它扩展到您的 eventList
状态数组中,这样它仍然是一个不错的平面数组。
此外,正如@Ashish 所指出的,您的 useEffect
钩子用法是无效的,并且通过放置在条件块中而违反了钩子的规则。效果需要在组件的主体中,因此应该在效果回调中测试条件。将匿名 async
函数重构为标准命名函数,并在条件检查内调用效果回调。
useEffect(() => {
const getEvents = async () => {
const eventsList = await axios.get("http://localhost:3000/api/dashboard");
console.log(eventsList.data);
const response = eventsList.data;
setEventList((eventList) => [
...eventList, // <-- copy previous state
...response, // <-- spread array response
]);
if (!response) {
setErrorMsg("Please create Event and then add User !!");
}
};
if (!props.profileData) { // <-- check condition for fetching data
getEvents();
}
}, []);
const eventListRender =
eventList.length > 0 ? (
eventList.map((item, index) => {
return <Carousel.Item key={index}>{item.eventName}</Carousel.Item>;
})
) : (
<Carousel.Item>No upcoming events</Carousel.Item>
);
使用模拟 axios 数据获取的演示。