React TS 如何等待props加载完成后再调用依赖props的函数
问题原因分析
- 异步数据渲染时序差:你使用的
useFetch是异步请求逻辑,父组件首次渲染时data为初始值,即使你加了data &&的条件渲染,如果useFetch的初始data被设置为空对象,空对象的真值判断会通过,此时data.skills和data.n_skills_columns均为undefined,传递给子组件的入参自然为空。 - 副作用依赖配置错误:你后续修改的代码中
useEffect的依赖数组为空,这会导致该逻辑仅在子组件首次挂载时执行一次。如果挂载时父组件的异步请求还未完成,skills_和columns_还未拿到有效值,后续父组件请求完成更新props时,这个副作用不会重新触发,state的值永远不会同步更新为最新的props。 - 渲染和副作用的执行时机差:你在
useEffect中能打印到正常props,是因为useEffect是组件渲染完成后异步执行的,打印时异步请求已经完成、props已经更新;但sliceArray调用是在渲染阶段同步执行的,使用的是当前渲染周期的props/state值,此时值还是undefined,所以会报错。
解决方案
方案1:直接添加参数默认值(最推荐,无多余逻辑)
不需要将props转存本地state,直接在组件参数处设置兜底默认值即可避免入参为undefined的问题:
const Skills: FC<SkillsProps> = ({ skills = [], columns = 1 }): JSX.Element => { const skillsTable = sliceArray(skills, columns); return ( <div> {skillsTable.map(/* 你的渲染逻辑 */)} </div> ); };
方案2:修正useEffect依赖配置
如果确实需要将props存入本地state(比如子组件内需要修改这些值),请给useEffect添加正确的依赖项,保证props更新时同步更新state:
const Skills: FC<SkillsProps> = ({ skills_, columns_ }): JSX.Element => { const [skills, setSkills] = useState([]); const [columns, setColumns] = useState(1); // 将props加入依赖数组,props变化时自动同步到state useEffect(() => { skills_ && setSkills(skills_); columns_ && setColumns(columns_); }, [skills_, columns_]); const skillsTable = sliceArray(skills, columns); // 后续渲染逻辑 };
方案3:父组件传递props时兜底
也可以在父组件传递参数时就做非空兜底,避免传递undefined给子组件:
<Skills skills={data.skills ?? []} columns={data.n_skills_columns ?? 1} />
内容的提问来源于stack exchange,提问作者DSteman
相关产品推荐
相关产品推荐

