如何将React自定义Hook转换为可在回调、事件处理中传参调用的普通函数
解决方案
你原来的自定义Hook不符合React Hook调用规则,Hook不能在回调、循环内调用,且Hook内部的useEffect是用于监听参数变化自动执行副作用,你需要的是主动触发时才dispatch action,所以可以按以下两种方式改造:
方案1:直接封装为普通工具函数
函数定义
// 可单独抽离到公共工具文件 const setTwoObjects = (dispatch, actions, { object1Name, object1Id, object2Name, object2Id }) => { dispatch(actions.action1({ object1Name, object1Id })); dispatch(actions.action2({ object2Name, object2Id })); };
组件内使用
首先在组件顶层调用useDispatch获取稳定的dispatch实例,再在任意场景调用普通函数即可:
import { useDispatch } from 'react-redux'; import { myTestSlice } from './你的切片存放路径'; function YourComponent() { const dispatch = useDispatch(); // 必须在组件顶层调用,符合Hook规则 // 场景1:在useEffect内循环调用 useEffect(() => { myData.forEach((data) => // 无返回值的遍历用forEach更合适 setTwoObjects(dispatch, myTestSlice.actions, { object1Name: data.object1Name, object1Id: data.object1Id, object2Name: data.object2Name, object2Id: data.object2Id }) ); }, [myData, dispatch]); // 场景2:在事件处理函数内调用 const handleSelect = (e, value) => { const newData = value; setTwoObjects(dispatch, myTestSlice.actions, { object1Name: newData.object1Name, object1Id: newData.object1Id, object2Name: newData.object2Name, object2Id: newData.object2Id, }); }; // 其余组件逻辑... }
方案2:封装为返回普通函数的自定义Hook(更简洁,无需每次传dispatch)
如果不想每次调用都传入dispatch,可以封装一个轻量自定义Hook,提前拿到dispatch后返回可自由调用的普通函数:
Hook定义
import { useDispatch, useCallback } from 'react'; const useSetTwoObjects = () => { const dispatch = useDispatch(); // 用useCallback包裹保证返回函数引用稳定,避免不必要的重渲染 return useCallback((actions, { object1Name, object1Id, object2Name, object2Id }) => { dispatch(actions.action1({ object1Name, object1Id })); dispatch(actions.action2({ object2Name, object2Id })); }, [dispatch]); };
组件内使用
import { myTestSlice } from './你的切片存放路径'; import { useSetTwoObjects } from './Hook存放路径'; function YourComponent() { const setTwoObjects = useSetTwoObjects(); // 组件顶层调用Hook,符合规则 // 场景1:在useEffect内循环调用 useEffect(() => { myData.forEach((data) => setTwoObjects(myTestSlice.actions, { object1Name: data.object1Name, object1Id: data.object1Id, object2Name: data.object2Name, object2Id: data.object2Id }) ); }, [myData, setTwoObjects]); // 场景2:在事件处理函数内调用 const handleSelect = (e, value) => { const newData = value; setTwoObjects(myTestSlice.actions, { object1Name: newData.object1Name, object1Id: newData.object1Id, object2Name: newData.object2Name, object2Id: newData.object2Id, }); }; // 其余组件逻辑... }
内容的提问来源于stack exchange,提问作者spspli
相关产品推荐
相关产品推荐

