React+Redux使用useEffect时报Cannot read properties of undefined (reading 'map')错误
问题根源
你的报错本质和useEffect本身无关,是未做空值防护导致的类型错误:
- Redux的
shopDetails状态初始化时,shop字段默认值为undefined。useEffect里的接口请求是组件首次渲染完成后才触发的,首次渲染同步执行到返回的JSX时,请求还未返回,shop仍为空值 - 你把读取
shop.name的标题写在了错误判断的外部,就算请求失败触发error,代码依然会先读取shop.name直接抛出错误,不会走到错误提示的分支
修复方案
方案1:加空值防护+调整结构顺序(成本最低)
修改2处逻辑即可:
- 解构
shopDetails时给shop加默认空对象 - 把标题移到错误判断的成功分支内,同时给链式读取的属性加可选链防护
修改后的完整代码如下:
const ProductListScreen = ({ match }) => { const dispatch = useDispatch() const shopDetails = useSelector((state) => state.shopDetails) // 给shop加默认空对象,避免解构后shop为undefined const { loading, error, shop = {} } = shopDetails useEffect(() => { dispatch(shopDetail(match.params.shopid)) }, [dispatch, match]) if (loading) { return ( <div className='loader'> <Loader /> </div> ) } return ( <> <Link className='btn btn-dark my-3' to='/'> Go Back </Link> {error ? ( <Message variant='warning' color='red'> {error} </Message> ) : ( <> {/* 把标题移到成功分支内,加可选链防止shop为空时报错 */} <h3>{shop?.name} Products</h3> <Row> {shop?.products?.map((product) => ( <Col key={product._id} sm={12} md={6} lg={4} xl={3}> <Product product={product} shopId={shop._id} /> </Col> ))} </Row> </> )} </> ) }
方案2:调整Redux初始状态
如果不想修改组件代码,也可以直接修改shopDetails对应的reducer初始值,把shop的默认值设为{ products: [] },这样首次渲染时读取shop.name也不会抛出类型错误,最多显示为空。
内容的提问来源于stack exchange,提问作者Zoheb Ahmed
相关产品推荐
相关产品推荐

