useDispatch() 错误:找不到 react-redux 上下文值;请确保组件包装在 <Provider>
Posted
技术标签:
【中文标题】useDispatch() 错误:找不到 react-redux 上下文值;请确保组件包装在 <Provider>【英文标题】:useDispatch() Error: Could not find react-redux context value; please ensure the component is wrapped in a <Provider> 【发布时间】:2020-06-05 08:07:35 【问题描述】:我正在尝试使用 React-Redux 库,但我收到标题错误。我用 Provider 包装了我的组件,但我仍然得到错误,只有当我实现 useDispatch() 钩子时。
应用程序运行良好,直到我添加了 useDispatch() 行。可以删除有关调度功能的其余行,但我仍然得到相同的错误。
如果您能帮助我,我将不胜感激。谢谢
这是我的代码:
import 'react-native-gesture-handler';
import NavigationContainer from '@react-navigation/native';
import Navigator from './navigation/Navigator';
import React, useEffect, useState, useCallback from 'react';
import SafeAreaView, StyleSheet, Text, View from 'react-native';
import createStore, combineReducers from 'redux';
import Provider, useDispatch from 'react-redux';
import dataReducer from './store/reducers/dataReducer';
import CONSTANTS from './constants/constants';
import saveInitialData from './store/actions/dataActions';
const App = () =>
const [fetched, setFetched] = useState(initialState);
const dispatch = useDispatch();
const saveInitialDataHandler = useCallback(data =>
dispatch(saveInitialData(data));
callback;
, []);
const rootReducer = combineReducers(
content: dataReducer,
);
const store = createStore(rootReducer);
useEffect(() =>
fetchData();
, []);
const fetchData = () =>
fetch(CONSTANTS.database)
.then(response => response.json())
.then(responseJSON =>
setFetched(true);
saveInitialDataHandler(responseJSON);
);
;
if (!fetched)
return (
<Provider store=store>
<View stlye=flex: 1, alignItems: 'center', justifyContent: 'center'>
<Text></Text>
</View>
</Provider>
);
else
return (
<Provider store=store>
<NavigationContainer>
<SafeAreaView style=styles.SafeAreaView>
<Navigator></Navigator>
</SafeAreaView>
</NavigationContainer>
</Provider>
);
;
const styles = StyleSheet.create(
SafeAreaView: flex: 1,
);
export default App;
【问题讨论】:
【参考方案1】:App
必须包含在 provider 中,因为您在其中使用了 useDispatch
。现在还只是个孩子。 Provider
设置上下文,因此只有其子级才能访问它,而不是父级。
一种解决方案是为其创建一个包装器组件:
const AppWrapper = () =>
const store = createStore(rootReducer);
return (
<Provider store=store> // Set context
<App /> // Now App has access to context
</Provider>
)
const App = () =>
const dispatch = useDispatch(); // Works!
...
【讨论】:
谢谢,它成功了。对于任何使用它的人,还记得导出您的 AppWrapper,而不是您的 App! 基本上确保使用 Provider 而不是 index.js 文件来包装您的 App 组件,该文件将 App 组件安装到 DOM。 您好,我遇到了同样的问题,当我尝试这种方法时,我收到“ReferenceError:找不到变量:rootReducer”rootReducer
是 OP 给他们的组合减速器的名称,您的名称可能会有所不同,具体取决于您如何设置减速器并导入它们。【参考方案2】:
也许您将 Provider 导入到 App.js 文件中。 Provider需要导入到文件index.js中。
/*index.js*/
import React from 'react';
import ReactDOM from 'react-dom';
import Provider from 'react-redux';
import store from './store/reduxStore';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<Provider store=store>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
【讨论】:
【参考方案3】:如果您在运行npm run test
时遇到此错误,则问题与您的测试文件有关。
通过以下代码更新或替换您的app.test.tsx
注意:如果您还没有安装redux-mock-store
,请不要忘记安装。
import React from 'react';
import render from '@testing-library/react';
import App from './App';
import Provider from 'react-redux';
import configureStore from 'redux-mock-store';
describe('With React Testing Library', () =>
const initialState = output: 10 ;
const mockStore = configureStore();
let store;
it('Shows "Hello world!"', () =>
store = mockStore(initialState);
const getByText = render(
<Provider store=store>
<App />
</Provider>
);
expect(getByText('Hello World!')).not.toBeNull();
);
);
我在搜索 1 小时后得到了这个解决方案。 非常感谢OSTE
原解决方案:Github issues/8145 and solution link
使用此解决方案,如果您遇到 TypeError: window.matchMedia is not a function 之类的错误,请通过此方式解决。将这些行添加到您的 setupTests.ts
文件中。原解决方案链接***.com/a/64872224/5404861
global.matchMedia = global.matchMedia || function ()
return
addListener: jest.fn(),
removeListener: jest.fn(),
;
;
【讨论】:
【参考方案4】:我对 react-native 应用程序的同一个 index.js 文件执行了此操作。 这样,您就不必导出和添加另一个文件,只是为了用提供者包装应用程序。
const ReduxProvider = () =>
return(
<Provider store=store>
<App />
</Provider>
)
AppRegistry.registerComponent(appName, () => ReduxProvider);
【讨论】:
【参考方案5】:发生在我身上,当我将 React 组件作为函数调用时,没有将其用作虚拟 dom,Comp 被独立调用,而不是呈现为某个元素的子元素
function Comp()
const a = useSelector(selectA); // throws error
Comp();
所以在我的情况下,解决方案是调用 Comp 和一个组件,而不是作为一个函数
即<Comp />
【讨论】:
所以。解决方案是什么? 解决方案是使用一级间接 - 即在 Comp 中调用选择器。这也是公认的解决方案。以上是关于useDispatch() 错误:找不到 react-redux 上下文值;请确保组件包装在 <Provider>的主要内容,如果未能解决你的问题,请参考以下文章
找不到模块“react-scroll-to-bottom”的声明文件
React-redux useDispatch() Uncaught TypeError