React函数组件中如何向子组件传递state并调用子组件函数使用该状态?
函数组件中子组件响应父传入状态、等效于
componentDidUpdate的实现方案 类组件中componentDidUpdate的触发规则很明确:组件完成首次挂载后,只有当自身props、state变化触发更新完成时,才会执行指定回调。函数组件要实现完全一致的能力,靠useEffect配合简单的状态判断就能实现,之前试了没出预期效果,基本都是依赖配置写错、触发时机没对齐导致的。
分场景落地实现
场景1:严格对齐类组件componentDidUpdate(排除首次挂载的执行)
useEffect默认的触发时机是:首次渲染完成就跑一次,之后只要依赖变了就跑。这和componentDidUpdate不触发首次挂载的规则有差异,需要用ref做首次渲染的判断:
import { useEffect, useRef } from 'react'; // 父组件传入的状态、需要调用的处理方法,都通过props传递到子组件 function ChildComponent({ incomingState, stateHandler }) { // 用ref缓存上一次接收到的状态值 const prevStateRef = useRef(); useEffect(() => { // 首次渲染时ref没有初始值,直接跳过,不执行业务逻辑 if (prevStateRef.current === undefined) { prevStateRef.current = incomingState; return; } // 这里写的逻辑,和类组件componentDidUpdate里写的代码效果完全一致 stateHandler(incomingState); // 更新缓存的状态值,给下一次渲染做对比 prevStateRef.current = incomingState; }, [incomingState, stateHandler]); return <div>子组件渲染内容</div>; }
场景2:允许首次挂载时同步执行对应逻辑
如果不需要严格规避首次触发,直接把要监听的传入状态配成useEffect的依赖就行,写起来更简单:
function ChildComponent({ incomingState, stateHandler }) { // 监听传入的状态,首次挂载、后续状态更新时,都会自动调用对应的处理方法 useEffect(() => { stateHandler(incomingState); }, [incomingState, stateHandler]); return <div>子组件渲染内容</div>; }
常见踩坑点
- 千万别省略
useEffect的依赖数组。省略依赖会导致组件每次重渲染都执行回调,和传入状态的变化完全脱钩,很容易出现逻辑误触发、无限循环的问题。 - 别随便写空依赖数组。空依赖数组的逻辑只会在组件首次挂载时跑一次,后续父组件传新的状态进来完全不会被监听到,和要实现的需求根本不匹配。
- 注意引用类型props的稳定性。如果传入的状态、处理方法是对象、数组、函数这类引用类型,没有做引用稳定化处理的话,父组件每次重渲染都会生成新的引用,哪怕内容一点没变,也会触发
useEffect执行。这时候可以按需用useCallback、useMemo包裹父组件中传入的内容,保证引用稳定。
内容的提问来源于stack exchange,提问作者Azhar
相关产品推荐
相关产品推荐

