javascript - × TypeError : Cannot read properties of undefined (reading 'getState' )

标签 javascript reactjs redux react-redux jsx

我是初学者,学习 React 和 redux。我写了这个关于如何在 redux 中使用 connect.js 的演示。搜索此类问题,但我的代码没有正确答案。我有一个未定义的上下文。是错字吗?还是我以错误的方式传递了上下文?提前致谢。这是我的代码。
index.js

import React from "react";
import ReactDOM from "react-dom";
import store from "./store";

import { Provider } from "react-redux";
import App from "./App";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
/store/index.js
import { createStore } from "redux";
import reducer from "./reducer.js";
const store = createStore(reducer);
export default store;
/store/reducer.js
import { ADD, SUB, MUL, DIV } from './constants.js'

// or initialState
const defaultState = {
  counter: 0
}

function reducer(state = defaultState, action) {
  switch (action.type) {
    case ADD:
      return {...state, counter: state.counter + action.num};
    case SUB:
      return {...state, counter: state.counter - action.num};
    case MUL:
      return {...state, counter: state.counter * action.num};
    case DIV:
      return {...state, counter: state.counter / action.num};
    default:
      return state;
  }
}

export default reducer
连接.js
import React, { PureComponent } from "react";
import { StoreContext } from "./context";

export default function connect(mapStateToProps, mapDispatchToProps) {
  return function enhanceHOC(WrappedCpn) {
    class EnhanceCpn extends PureComponent {
      constructor(props, context) {
        super(props, context);
        console.log('connect props', props);
        console.log('connect context', context);  // context is undefined here
        this.state = {
          storeState: mapStateToProps(context.getState()),
        };
      }

      componentDidMount() {
        this.unSubscribe = this.context.subscribe(() => {
          this.setState({
            counter: mapStateToProps(this.context.getState()),
          });
        });
      }

      componentWillUnmount() {
        this.unSubscribe();
      }

      render() {
        return (
          <WrappedCpn
            {...this.props}
            {...mapStateToProps(this.context.getState())}
            {...mapDispatchToProps(this.context.dispatch)}
          />
        );
      }
    }
    EnhanceCpn.contextType = StoreContext;
    return EnhanceCpn;
  };
}
上下文.js
import React from "react";
const StoreContext = React.createContext();
export {
  StoreContext
}
应用程序.js
import React, { PureComponent } from 'react'
import My from './pages/my'

export default class App extends PureComponent {
  constructor(props, context) {
    super(props, context);

    console.log('APP props', props);
    console.log('APP context', context); // context got value
  }

  render() {
    return (
      <div>
        <My />
      </div>
    )
  }
}
我的.js
import React, { PureComponent } from 'react'
import { sub, mul } from '../store/actionCreators'
import connect from '../utils/connect'

class My extends PureComponent {

  render() {
    return (
      <div>
      <h3>my</h3>
      <h3>counter: { this.props.counter }</h3>
      <button onClick={e => this.props.subNum()}>-2</button>
      <button onClick={e => this.props.mulNUm(5)}>*5</button>
    </div>
    )
  }
}

const mapStateToProps = state => ({
  counter: state.counter
})

const mapDispatchToProps = dispatch => ({
  subNum: (num = -2) => {
    dispatch(sub(num))
  },
  mulNUm: num => {
    dispatch(mul(num))
  }

})

export default connect(mapStateToProps, mapDispatchToProps)(My)
actionCreators.js
import { ADD, SUB, MUL, DIV } from './constants.js'

export function add(num) {
  return {
    type: ADD,
    num
  }
}

export const sub = (num) => {
  return {
    type: SUB,
    num
  }
}

export const mul = (num) => ({
  type: MUL,
  num
})

export const div = num => ({
  type: DIV,
  num
})
常量.js
const ADD = 'ADD_ACTION'
const SUB = 'SUB_ACTION'
const MUL = 'MUL_ACTION'
const DIV = 'DIV_ACTION'

export { ADD, SUB, MUL, DIV }

最佳答案

来自 docs ,这是关于 Class.contextType 的内容:

The contextType property on a class can be assigned a Context object created by React.createContext(). Using this property lets you consume the nearest current value of that Context type using this.context. You can reference this in any of the lifecycle methods including the render function.


在您的情况下,您似乎只是错过了传递您的自定义 StoreContext还原 Providercontext Prop
您需要执行以下操作:
import React from "react";
import ReactDOM from "react-dom";
import store from "./store";
import { StoreContext } from "./context";

import { Provider } from "react-redux";
import App from "./App";

ReactDOM.render(
  <Provider store={store} context={StoreContext}>
    <App />
  </Provider>,
  document.getElementById("root")
);
另见 https://react-redux.js.org/using-react-redux/accessing-store#providing-custom-context

关于javascript - × TypeError : Cannot read properties of undefined (reading 'getState' ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69156907/

相关文章:

javascript - 如何重启程序重新开始?

javascript - ES5中如何实现从服务器返回的图像延迟加载?

javascript - 在 react.js 中的 anchor 标记中添加参数

javascript - 如何取消订阅 mobx-state-tree 中的 onSnaphot() ?

javascript - 使用 React 如何切换容器组件中嵌套组件的可见性?

javascript - bootstrap main.js 和 plugins.js 脚本有什么用?

javascript - jsPDF - 具有 rowspan 和 colspan 属性的标题表

javascript - react Redux : My React component not receive updated array as props

reactjs - 如何使用 Vagrant VM 通过共享文件夹启用热重载?

javascript - 通过 redux 更改状态后如何更新 React 组件?