如何在Redux中存储布尔值实现跨页面渲染并解决测试Mock报错
问题根因
你原来直接导出变量的写法存在两个核心问题:
- 完全脱离React响应式体系,变量修改后不会触发页面重渲染,就算值更新了UI也不会同步变化
- 模块导出的原始值在测试环境下会被处理为只读属性,自然无法直接Mock修改
Redux(官方推荐Redux Toolkit写法,无冗余模板代码)实现步骤
按步骤直接复用代码即可,不需要掌握复杂的原生Redux概念:
1. 安装依赖
npm install @reduxjs/toolkit react-redux
2. 编写权限状态Slice
新建文件src/store/permissionSlice.js,专门存储这个布尔值和对应的修改方法:
import { createSlice } from '@reduxjs/toolkit' // 定义初始状态 const initialState = { isTrue: false } export const permissionSlice = createSlice({ name: 'permission', initialState, reducers: { // 定义修改isTrue的方法,调用时传入新的布尔值即可 setIsTrue: (state, action) => { state.isTrue = action.payload } } }) // 导出修改方法,给存值的逻辑调用 export const { setIsTrue } = permissionSlice.actions // 导出reducer用于全局Store注册 export default permissionSlice.reducer
3. 配置全局Store
新建文件src/store/index.js,把刚才的权限状态注册到全局Store:
import { configureStore } from '@reduxjs/toolkit' import permissionReducer from './permissionSlice' export const store = configureStore({ reducer: { permission: permissionReducer } })
4. 根组件注入Store
打开项目入口文件src/index.js,用Provider包裹整个应用,让所有页面都能访问全局状态:
import React from 'react' import ReactDOM from 'react-dom/client' import { Provider } from 'react-redux' import { store } from './store' import App from './App' const root = ReactDOM.createRoot(document.getElementById('root')) root.render( <Provider store={store}> <App /> </Provider> )
5. 存入布尔值
在你原本获取permissionSender值的位置,用dispatch把值存到Redux中:
import { useDispatch } from 'react-redux' import { setIsTrue } from './store/permissionSlice' // 你原本引入permissionSender的路径 import { permissionSender } from 'xxx' function PermissionEntry() { const dispatch = useDispatch() // 拿到权限值后直接同步到全局 const { isTrue = false } = permissionSender dispatch(setIsTrue(isTrue)) return <div>页面其他业务内容</div> }
6. 目标页面取值渲染
在需要显示警告的页面,通过useSelector取全局值做条件渲染即可,注意变量名大小写,你原来写的小驼峰错误istrue会触发未定义报错:
import { useSelector } from 'react-redux' function TargetPage() { // 从全局Store读取isTrue的值,值变化时会自动触发页面重渲染 const isTrue = useSelector(state => state.permission.isTrue) return ( <div> {/* 其他页面内容 */} {isTrue && <WarningMessage />} </div> ) }
测试时Mock值的方法
不需要硬改全局变量,测试时直接给被测组件包裹一层Provider,传入自定义初始值的Store即可:
import { render } from '@testing-library/react' import { configureStore } from '@reduxjs/toolkit' import { Provider } from 'react-redux' import permissionReducer from './store/permissionSlice' import TargetPage from './TargetPage' test('isTrue为true时正常渲染警告信息', () => { // 创建测试专用Store,把isTrue初始值设为需要Mock的状态 const testStore = configureStore({ reducer: { permission: permissionReducer }, preloadedState: { permission: { isTrue: true } } }) render( <Provider store={testStore}> <TargetPage /> </Provider> ) // 后续写断言判断警告组件是否正常渲染即可 })
如果你的项目全局状态极少,只有这一个布尔值需要跨页面传递,也可以用React Context实现,比Redux更轻量;但如果后续还要新增用户信息、权限列表、主题配置等全局状态,用上面的Redux Toolkit方案扩展性更好。
内容的提问来源于stack exchange,提问作者Noob
相关产品推荐
相关产品推荐

