在set了useState之后,如何保证代码在由set引发的useEffect之后执行?-灵析社区

silennn

有父子两个组件 父子都有一个数组 父组件的数组list更新, 子组件的数组tableData会跟着更新,并显示在表格上. 现在有个新增的按钮, 要求在新增时 先更新一下表格 再插入新的一行. 但是更新表格是在父组件请求,子组件通过useEffect跟着更新,导致新增时插入的一行被覆盖了(useEffect更新的逻辑比插入逻辑晚导致被覆盖),要怎么处理. // 父组件 const Father = () => { const [list, setList] = useState([]) const getListData = async () => { // 请求获取list数据 const res = await getList().catch(() => {}) setList(res.data) } return () } // 子组件 const Son = ({list, getListData}) => { const [tableData, setTableData] = useState([]) // 当父组件的数据更新时 子组件也跟着更新 useEffect(() => { setTableData(list) }, [list]) // 新增 const onAdd = async () => { // 在新增之前先获取一下最新的表格数据list 调用父组件的请求函数 因为useEffect 当前子组件的tableData也会更新一下 await getListData() // 给当前组件的表格数据添加一行新增的空行(不改变父组件的数据) 但是由于这里会先于useEffect执行 所以会被覆盖 没有效果 setTableData([{空行数据}, ...tableData]) } return ( 新增 ) } 一个办法是把新增一行的逻辑移到useEffect处,加上判断来执行. 但明显这么写很不友好.

阅读量:15

点赞量:0

问AI
这其实是一个组件设计上的问题,用于渲染的表格数据只需要有一份即可,通常作为根组件的 state 是没问题的。但你这里子组件又维护了一份 state,对于组件的渲染来说形成了一个双数据源,不仅容易造成你描述的这种问题,也无端增加了开发过程的心智负担。 正确的做法是 "子组件" 直接使用父组件传过来的 list 去渲染,不用再存一个 state,如果存在子组件需要更新父组件的 state 的情况,应该从父组件传一个用于更新的方法给子组件。 总之保证 "渲染数据的单一性" 以及 "更新数据方式的唯一性" 基本上就能避免这种问题的出现 比较简单的处理方式如下 // 父组件 const Father = () => { const [list, setList] = useState([]) const getListData = async () => { // 请求获取list数据 const res = await getList().catch(() => {}) setList(res.data) } return () } // 子组件 const Son = ({list, setList, getListData}) => { // 新增 const onAdd = async () => { await getListData() setList((prevList) => [{空行数据}, ...prevList]) } return ( 新增 ) }