useDispatch() 错误:找不到 react-redux 上下文值;请确保组件被包裹在 <Provider> 中

IT技术 reactjs react-native redux react-redux
2021-05-19 03:30:08

我正在尝试使用 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;
4个回答

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!
...

也许您将 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')
);

我在一个 react-native 应用程序的同一个 index.js 文件上做了这个。通过这种方式,您不必导出和添加另一个文件,只是为了使用提供程序包装应用程序。

const ReduxProvider = () => {
    return(
        <Provider store={store}>
            <App />
        </Provider>
    )
}

AppRegistry.registerComponent(appName, () => ReduxProvider);

发生在我身上,当我将 React 组件作为函数调用时,没有将其用作虚拟 dom,Comp 被独立调用,而不是渲染为某个元素的子元素

function Comp() {
  const a = useSelector(selectA); // throws error
}
Comp();

所以在我的情况下,解决方案是调用 Comp 和一个组件,而不是作为一个函数,即 <Comp />