首页 > 解决方案 > 如何将 react-redux 与下一个 js 和类组件一起使用

问题描述

我正在尝试将 redux 与 NextJS 和类组件一起使用,但无法弄清楚如何摆脱此错误:

错误:在“Connect(CounterDisplay)”的上下文中找不到“store”。要么将根组件包装在 <Provider> 中,要么将自定义的 React 上下文提供者传递给连接选项中的 Connect(CounterDisplay),并将相应的 React 上下文消费者传递给。

// pages/_app.js

import '../styles/globals.css';
import 'bootstrap/dist/css/bootstrap.css';
import {Provider} from 'react-redux';
import {useStore} from '../core/redux/store';

export default function App({Component, pageProps}) {
  const store = useStore(pageProps.initialReduxState);

  return (
      <Provider store={store}>
        <Component {...pageProps} />
      </Provider>
  );
}
// pages/index.js

import React from 'react';
import Page from '../components/page'
import CounterDisplay from '../components/CounterDisplay';

export default function Index() {
  // return <Page />
  return (
      <React.Fragment>
        <CounterDisplay/>
      </React.Fragment>
  )
}
// components/CounterDisplay.js

import React from 'react';
import connect from 'react-redux/lib/connect/connect';

class CounterDisplay extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
        <div>
          <span>{this.props.count}</span>
        </div>
    );
  }
}


function mapStateToProps(state, ownProps) {
  return {
    count: state.count
  }
}

export default connect(mapStateToProps)(CounterDisplay);

奇怪的是我已经将根组件包装在 <Provider> 中,因此根据错误消息它应该可以正常工作。

编辑:

// core/redux/store

import {useMemo} from 'react';
import {createStore, applyMiddleware} from 'redux';
import {composeWithDevTools} from 'redux-devtools-extension';

let store;

const initialState = {
  lastUpdate: 0,
  light: false,
  count: 0,
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'TICK':
      return {
        ...state,
        lastUpdate: action.lastUpdate,
        light: !!action.light,
      };
    case 'INCREMENT':
      return {
        ...state,
        count: state.count + 1,
      };
    case 'DECREMENT':
      return {
        ...state,
        count: state.count - 1,
      };
    case 'RESET':
      return {
        ...state,
        count: initialState.count,
      };
    default:
      return state;
  }
};

function initStore(preloadedState = initialState) {
  return createStore(
      reducer,
      preloadedState,
      composeWithDevTools(applyMiddleware()),
  );
}

export const initializeStore = (preloadedState) => {
  let _store = store ?? initStore(preloadedState);

  // After navigating to a page with an initial Redux state, merge that state
  // with the current state in the store, and create a new store
  if (preloadedState && store) {
    _store = initStore({
      ...store.getState(),
      ...preloadedState,
    });
    // Reset the current store
    store = undefined;
  }

  // For SSG and SSR always create a new store
  if (typeof window === 'undefined') return _store;
  // Create the store once in the client
  if (!store) store = _store;

  return _store;
};

export function useStore(initialState) {
  const store = useMemo(() => initializeStore(initialState), [initialState]);
  return store;
}

标签: reactjsreduxreact-reduxnext.js

解决方案


在您的CounterDisplay组件中,您需要更改以下内容的导入connect

import connect from 'react-redux/lib/connect/connect';

行至:

import {connect} from 'react-redux';

react-redux如果您不从插件的根文件夹中导入它,很可能看不到同一个商店。


推荐阅读