如何使用React Hooks与Redux将数据库获取的数据正确传入对象
问题原因
useState 仅在组件首次渲染时读取你传入的初始值,后续组件重渲染不会重新计算初始值。你首次渲染时orders是空数组,因此columns的初始newOrder.items直接被设为空。后续你调用setOrders更新orders时,columns的状态不会自动同步,所以一直是空数组。
解决方案
你可以根据自己的业务场景选以下任意一种方案:
方案1:同步orders更新到columns(适用需要单独修改columns状态的场景,比如拖拽看板场景)
新增useEffect监听orders变化,自动更新columns对应字段:
const [orders, setOrders] = useState([]); const [columns, setColumns] = useState({ newOrder: { name: "Requested", items: [] }, x: { name: "x", items: [] } }); useEffect(() => { props.fetchOrder(setOrders); }, []); // 新增监听orders的effect useEffect(() => { setColumns(prevState => ({ ...prevState, newOrder: { ...prevState.newOrder, items: orders } })); }, [orders])
方案2:不把columns存为状态(适用仅展示、不需要单独修改columns的场景)
如果你的columns后续不会独立做状态更新(比如不需要修改其中的字段、仅做渲染用),可以直接去掉columns的useState定义,每次渲染自动用最新的orders计算即可:
const [orders, setOrders] = useState([]); useEffect(() => { props.fetchOrder(setOrders); }, []); // 直接定义columns,不要用useState包裹 const columns = { newOrder: { name: "Requested", items: orders }, x: { name: "x", items: [] } };
优化建议
你当前已经接入了Redux,其实不需要把组件的setOrders方法传入action,更符合Redux规范的写法是直接从store取orders数据:
- 先修改action:
export const fetchOrder = () => dispatch => { fetch("/api/orders") .then(res => res.json()) .then(data => { dispatch({ type: FETCH_ORDER, payload: data }); }); };
- 组件内从Redux取数:
import { useDispatch, useSelector } from 'react-redux' // 组件内代码 const dispatch = useDispatch() // 替换为你自己的Redux state中orders对应的取值路径 const orders = useSelector(state => state.orders) const [columns, setColumns] = useState({ newOrder: { name: "Requested", items: [] }, x: { name: "x", items: [] } }); useEffect(() => { dispatch(fetchOrder()) }, [dispatch]) useEffect(() => { setColumns(prevState => ({ ...prevState, newOrder: { ...prevState.newOrder, items: orders } })); }, [orders])
内容的提问来源于stack exchange,提问作者Nadav Yair
相关产品推荐
相关产品推荐

