useEffect空依赖数组仍无限运行 派发thunk加载表格数据问题咨询
问题根因
你代码里的两个错误直接导致了无限循环:
- useEffect返回的清理函数格式错误:useEffect要求返回函数作为清理逻辑,你直接写
return setDidFetch(false)等于在useEffect回调执行时同步立即触发状态修改,而非等到组件卸载时才执行。 - 防抖状态未生效:你定义了
didFetch用来避免重复请求,但useEffect内完全没有增加对应判断,请求没有被拦截。
另外如果父组件传递的getCartItems是每次渲染都重新生成的匿名函数,也会进一步加重渲染循环问题。
修复方案
方案1:移除冗余的didFetch状态(更推荐)
空依赖的useEffect本身就只会在组件首次挂载时执行一次,不需要额外加防抖状态,同时把清理函数修正为函数格式:
const Cart = (props) => { useEffect( () => { async function fetchCart(){ await props.getCartItems(); } fetchCart() // 无清理逻辑可以省略返回,需要清理就包裹为函数 // return () => { 你的清理逻辑 } },[]); return ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> <TableHead> <TableRow> <TableCell>Product</TableCell> <TableCell align="right">Quantity</TableCell> <TableCell align="right">Total Cost</TableCell> </TableRow> </TableHead> <TableBody> {props.cartItems.map((item) => ( <TableRow key={item.product.name} sx={{ "&:last-child td, &:last-child th": { border: 0 } }} > <TableCell component="th" scope="row"> {item.product.name} </TableCell> <TableCell align="right">{item.quantity}</TableCell> <TableCell align="right"> {(item.quantity * item.product.price).toFixed(2)} </TableCell> <TableCell> <Button onClick={() => props.removeCartItem(item.id)}> Remove </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ); };
如果eslint报getCartItems的依赖警告,在父组件用useCallback包裹传递的getCartItems方法保证引用稳定,再把稳定后的props.getCartItems加入useEffect依赖数组即可。
方案2:保留didFetch防抖逻辑
如果你需要主动控制请求时机,保留didFetch的话调整逻辑如下:
const Cart = (props) => { const [didFetch, setDidFetch] = useState(false); useEffect( () => { // 已经请求过直接跳过 if (didFetch) return; async function fetchCart(){ await props.getCartItems(); setDidFetch(true); } fetchCart() // 清理逻辑包裹为函数,仅组件卸载时执行 return () => setDidFetch(false) },[didFetch]); // 渲染逻辑和之前一致 };
内容的提问来源于stack exchange,提问作者charmingduchess
相关产品推荐
相关产品推荐

