如何在React函数组件的导出函数中使用Redux状态与dispatch
问题原因
你的代码无法正常运行是两个规则共同作用的结果:
- JavaScript的作用域规则:
scenarios、dispatch这些变量是GenerateTree组件内部的局部变量,外部的generate函数属于独立的顶层作用域,没有权限访问组件内部的变量。 - React Hook调用规则:
useSelector、useDispatch这类Hook只能在函数组件顶层或者自定义Hook内部调用,不能在普通的全局函数里执行。
解决方案1:调用generate的逻辑在React组件/Hook中
把generate相关逻辑封装为自定义Hook即可,无需额外定义空组件:
import { useSelector, useDispatch } from "react-redux"; import { treeActions } from "../store/treedata-slice"; export const useGenerateTree = () => { const dispatch = useDispatch(); const pathways = useSelector((state) => state.tree.pathways); const pickedRenderElementType = useSelector( (state) => state.tree.pickedRenderElementType ); const pickedRenderElementValue = useSelector( (state) => state.tree.pickedRenderElementValue ); const scenarios = useSelector((state) => state.tree.scenarios); const treeData = useSelector((state) => state.tree.treeData); const generate = () => { const arr = scenarios; if (pickedRenderElementType === "scen") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } if (pickedRenderElementType === "path") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } if (pickedRenderElementType === "act") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } }; return { generate, treeData }; };
调用方式:
// 在需要使用的组件中引入调用 import { useGenerateTree } from './your-file-path' function BusinessComponent() { const { generate } = useGenerateTree() // 可在任意事件、副作用中调用generate return <button onClick={() => generate()}>生成树结构</button> }
解决方案2:调用generate的逻辑在普通JS文件/非React环境中
直接引入你项目中创建的Redux store实例,直接读取状态、调用dispatch即可,不需要依赖React Hook:
// 替换为你项目中导出store的路径,即你用configureStore创建store的文件 import store from '../store' import { treeActions } from "../store/treedata-slice"; export const generate = () => { // 读取调用瞬间的最新Redux状态 const treeState = store.getState().tree const scenarios = treeState.scenarios const pickedRenderElementType = treeState.pickedRenderElementType const dispatch = store.dispatch const arr = scenarios; if (pickedRenderElementType === "scen") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } if (pickedRenderElementType === "path") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } if (pickedRenderElementType === "act") { dispatch(treeActions.setTreeData(/* 构造树逻辑 */)); } };
注意:该方案中store.getState()只会返回调用时刻的状态快照,不会自动响应Redux状态更新,如果需要监听状态变化需要额外通过store.subscribe注册监听函数。
内容的提问来源于stack exchange,提问作者Phaki
相关产品推荐
相关产品推荐

