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

pes8fvy9  于 2022-11-30  发布在  React
关注(0)|答案(7)|浏览(384)

我正在尝试使用React-Redux库,但我在标题上看到了错误。我用Provider Package 了我的组件,但我仍然得到了错误,只有当我实现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;
z4bn682m

z4bn682m1#

App必须 Package 在provider中,因为您在其中使用useDispatch。目前它只是子系。Provider会设定内容,因此只有其子系可以存取它,而不是父系。
一种解决方案是为它创建一个 Package 组件:

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

vtwuwzda2#

可能您已将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')
);
3lxsmp7m

3lxsmp7m3#

如果在运行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问题/8145及解决方案链接
使用此解决方案时,如果出现类似TypeError:matchMedia不是一个函数那么用这种方法解决。添加这些行到你的setupTests.ts文件。原始解决方案链接stackoverflow.com/a/64872224/5404861

global.matchMedia = global.matchMedia || function () {
  return {
    addListener: jest.fn(),
    removeListener: jest.fn(),
  };
};
cotxawn7

cotxawn74#

我在同一个index.js文件上为一个react-native应用程序做了这件事。这样你就不必导出和添加另一个文件,只是为了用提供程序 Package 应用程序。

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

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

xkrw2x1b5#

当我把React组件作为函数调用,而不把它作为虚拟dom使用时,Comp被独立调用,而不是作为某个元素的子元素呈现

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

因此在我例子中,解决方案是调用Comp和一个组件,而不是作为一个函数,例如<Comp />

nhhxz33t

nhhxz33t6#

import store from "../redux/Store";

store?.dispatch(actions.setSocket({ socket }));

请先保存操作。如果组件未保存在提供程序中,则对该存储使用调度。

e0bqpujr

e0bqpujr7#

你不能打电话

const dispatch = useDispatch()

在不在容器内的组件中

<Provider store={store}></Provider>

正确示例:

const App = ({ Component, pageProps }: AppPropsWithLayout) => {
  const page = (
    <>
      <Component {...pageProps} />
      <Analytics />
    </>
  )

  if (Component.getLayout) {
    return <Provider store={store}>Component.getLayout(page)</Provider>
  }

  return (
    <Provider store={store}>
      <MainLayout>{page}</MainLayout>
    </Provider>
  )
}

相关问题