当前位置: 首页 > 知识库问答 >
问题:

×TypeError:无法读取未定义的属性(读取“获取状态”)

徐翔
2023-03-14

我是一个初学者,学习反应和还原。我写了这个关于如何在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;
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
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;
  };
}
import React from "react";
const StoreContext = React.createContext();
export {
  StoreContext
}
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>
    )
  }
}
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)
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
})

Constants.js

const ADD = 'ADD_ACTION'
const SUB = 'SUB_ACTION'
const MUL = 'MUL_ACTION'
const DIV = 'DIV_ACTION'

export { ADD, SUB, MUL, DIV }

共有1个答案

冀翰翮
2023-03-14

在文档中,下面是关于class.contextType:

类上的ContextType属性可以分配一个由react.createContext()创建的上下文对象。使用此属性可以使用this.Context使用该上下文类型的最近的当前值。您可以在任何生命周期方法中引用它,包括render函数。

在您的示例中,似乎没有将自定义StoreContext传递到使用Context道具redux提供程序

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")
);
 类似资料: