reactjs - 在 React 中使用 preloadedState 进行测试:在函数中手动导入存储时,redux 存储不同步
问题描述
我正在使用 react-testing-library 和 jest 为 React 编写测试,当另一个文件导入存储时,我在弄清楚如何为我的 redux 存储设置 preloadedState 时遇到了一些问题。
我有这样设置我的商店的功能
store.ts
export const history = createBrowserHistory()
export const makeStore = (initalState?: any) => configureStore({
reducer: createRootReducer(history),
preloadedState: initalState
})
export const store = makeStore()
和另一个像这样的js文件
实用程序.ts
import store from 'state/store'
const userIsDefined = () => {
const state = store.getState()
if (state.user === undefined) return false
...
return true
}
然后我有一个看起来像这样的测试:
utils.test.tsx(renderWithProvider 基本上是一个渲染函数,它也将我的组件包装在一个渲染组件中,请参阅:https ://redux.js.org/recipes/writing-tests#connected-components )
describe("Test", () => {
it("Runs the function when user is defined", async () => {
const store = makeStore({ user: { id_token: '1' } })
const { container } = renderWithProvider(
<SomeComponent></SomeComponent>,
store
);
})
})
<SomeComponent> 依次调用 utils.ts 中的函数
SomeComponent.tsx
const SomeComponent = () => {
if (userIsDefined() === false) return (<Forbidden/>)
...
}
现在..运行测试时会发生什么似乎是这样的。
- 读取utils.ts并从 'state/store'读取行导入存储,这将创建并保存尚未定义用户的存储变量。
- utils.test.tsx被调用并运行调用const store = makeStore({ user: { id_token: '1' } })的代码。
- renderWithProvider ()渲染SomeComponent进而调用userIsDefined函数。
- if ( state.user === undefined)返回 false 因为state.user仍然未定义,我认为这是因为utils.ts在我调用自己的makeStore({ user: { id_token: '1 ' } }) ?
我想要的答案:我想确保当再次调用 makeStore() 时,它会更新之前导入的 store 版本,该版本正在utils.ts中使用。有没有办法做到这一点,而不必使用useSelector()并将用户值从组件传递给我的 utils 函数?
例如,我可以做这样的事情,但我宁愿不这样做,因为我有更多这些文件和功能,并且很大程度上依赖于import store from 'state/store':
SomeComponent.tsx
const SomeComponent = () => {
const user = useSelector((state: IState) => state.user)
if (userIsDefined(user) === false) return (<Forbidden/>)
...
}
实用程序.ts
//import store from 'state/store'
const userIsDefined = (user) => {
//const state = store.getState()
if (user === undefined) return false
...
return true
}
正如我上面所说,我不想这样做。
(顺便说一句,我似乎无法为此创建一个小提琴,因为我不知道如何为测试和这个用例做这个)
感谢您提供任何帮助或推动正确的方向。
解决方案
这只是在您的应用程序中发现了一个错误:您正在使用对store
react 组件内部的直接访问,这是您永远不应该做的事情。当该状态更改并不同步时,您的组件将不会重新呈现。
如果您真的想要这样的助手,请用它制作一个自定义钩子:
import store from 'state/store'
const useUserIsDefined = () => {
const user = useSelector(state => state.user)
if (user === undefined) return false
...
return true
}
这样,您的助手不需要直接访问,store
并且当该存储值更改时组件将正确重新呈现。
推荐阅读
- asp.net-mvc - 仅为更新的文件创建 nuget 包
- maven - 无法使用 Gradle 插件在 Jenkins 中获取类型为 DefaultGroovyMavenDeployer 的对象的未知属性
- elasticsearch - Elasticsearch 查询 - 组合查询
- vue.js - Vuex mapState 设置状态
- sqlite - SQLite 返回的最小值大于最大值
- c++ - 无法编译 C++ 代码
- javascript - 跟踪html5视频控制区域中的点击播放按钮
- android - 移动应用安全
- excel - Excel VBA:列充满不可见的内容,直到结束(第 16,384 列)
- reactjs - React/Redux/Router 客户端登录凭据 - 受限页面