React 如何编写通用 callback 函数实现子组件向父组件传递 setState
解决方案
你可以通过封装通用自定义Hook的方式彻底消除这类重复代码,以下是可直接落地的实现方案:
方案1:单setter通用封装
先封装一个独立的自定义Hook,专门处理这类透传setter的useCallback包裹逻辑:
import { useCallback } from 'react'; // 通用Hook,接收原生setState函数作为入参 const usePassThroughSetter = (setter) => { return useCallback((val) => { setter(val); }, [setter]); };
使用时只需一行代码即可生成目标回调,完全消除重复逻辑:
// 原来的多行写法替换为下面一行即可 const setIsModalVisible = usePassThroughSetter(setModalVisible); // 新增其他状态回调也只需要同格式声明 const setFormVisible = usePassThroughSetter(setFormVisible);
React原生的setState函数本身是引用稳定的,因此依赖数组的声明完全安全,不会引发不必要的重渲染。
方案2:多setter批量生成
如果同一组件内有大量这类回调需要声明,可以进一步封装批量处理的Hook,一次性生成所有需要的回调:
import { useMemo } from 'react'; const useBulkSetters = (setterMap) => { return useMemo(() => { return Object.fromEntries( Object.entries(setterMap).map(([callbackName, setter]) => [ callbackName, (val) => setter(val) ]) ); }, [setterMap]); };
使用方式如下:
const [modalVisible, setModalVisible] = useState(false); const [count, setCount] = useState(0); const [formData, setFormData] = useState({}); // 一次性生成所有回调 const callbacks = useBulkSetters({ setIsModalVisible: setModalVisible, setCount: setCount, setFormData: setFormData }); // 子组件绑定直接使用 callbacks.setIsModalVisible 即可
额外优化提示
如果你对透传的值不需要做任何额外处理(比如格式转换、边界校验等),完全不需要额外包裹useCallback:React原生的setState函数本身引用永远稳定,你可以直接把setModalVisible这类原生setter传给子组件,即使子组件用React.memo包裹也不会触发不必要的重渲染,连Hook调用都可以省掉。
内容的提问来源于stack exchange,提问作者Oliver Darby
相关产品推荐
相关产品推荐

