React报错TypeError: Cannot read property 'map' of undefined 设初始值仍未解决
问题原因
- 直接在渲染方法
ShowList中调用setImageName、setImagePath这类状态更新方法:状态更新会触发组件重渲染,重渲染又会再次执行ShowList触发状态更新,形成无限重渲染死循环。 - 接口请求是异步操作,首次渲染时
state还是初始空数组,执行ImgArray[0]得到的是undefined,将undefined赋值给ImageName后调用ImageName.map就会触发“不是函数”的报错。 - 业务逻辑错误:当前代码将所有牛只的图片统一设置为第一头牛的图片列表,不符合每头牛展示自身对应图片的需求,完全不需要单独维护
ImageName、ImagePath两个状态。 ImagePath初始值设置为对象,后续赋值为字符串,类型不匹配,属于无意义的错误定义。
修正方案
直接删掉不必要的状态,去掉渲染过程中的状态更新操作,在遍历每头牛的时候直接遍历它自身的image字段即可,修正后的代码如下:
const ShowCattle = () => { const { lstate } = useContext(LoginContext); const [state, setstate] = useState([]); // 固定路径不需要存状态,直接定义常量即可 const ImagePath = '/upload/'; const ShowData = async () => { try { const res = await fetch('/show-cattles', { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ lstate }) }); const data = await res.json(); setstate(data); } catch (e) { console.log(e); } } const ShowList = () => { return state.map((cvalue, index) => { return ( <div key={index}> {/* 直接遍历当前牛只的image字段,遍历前加类型判断避免报错 */} { Array.isArray(cvalue.image) && cvalue.image.map((value, imgIndex) => { return ( <div key={imgIndex} > <img src={ImagePath + value} alt="img" /> <h6>Cattle Image Name : {value}</h6> </div> ) }) } <h6>Cattle Name : {cvalue.cattle_name}</h6> <h6>Cattle Type : {cvalue.cattle_type}</h6> <h6>Cattle Age : {cvalue.cattle_age}</h6> <h6>Cattle Description : {cvalue.cattle_des}</h6> <h6>Cattle City : {cvalue.cattle_city}</h6> <h6>Cattle Price : {cvalue.cattle_price}</h6> <hr /> </div> ) }) } useEffect(() => { ShowData(); }, []); return ( <> <Header /> <Container fluid> <Row> <Col className="my_body"> <h1>Show Cattle Page</h1> <br /> <br /> <ShowList /> </Col> </Row> </Container> </> ) }
补充优化点
- 数组遍历的key尽量用数据唯一ID代替索引,避免列表顺序变化时出现渲染异常。
- 可以新增加载状态,接口请求过程中展示加载提示,提升用户体验。
内容的提问来源于stack exchange,提问作者Muhammad Usman
相关产品推荐
相关产品推荐

