× TypeError: Cannot read properties of undefined (reading 'getState')
Posted
技术标签:
【中文标题】× TypeError: Cannot read properties of undefined (reading \'getState\')【英文标题】:× TypeError: Cannot read properties of undefined (reading 'getState')× TypeError: Cannot read properties of undefined (reading 'getState') 【发布时间】:2021-11-08 09:43:54 【问题描述】:我是初学者,正在学习 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
connect.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;
;
context.js
import React from "react";
const StoreContext = React.createContext();
export
StoreContext
App.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
)
constants.js
const ADD = 'ADD_ACTION'
const SUB = 'SUB_ACTION'
const MUL = 'MUL_ACTION'
const DIV = 'DIV_ACTION'
export ADD, SUB, MUL, DIV
【问题讨论】:
你的actionCreators
在哪里?
您是否想创建自己的connect
HOC 来娱乐或其他什么?为什么不使用/利用react-redux
?如果我没记错的话,React 不推荐使用 constructor(props, context)
签名。
我编辑我的问题并发布 actionCreators.js。是的,我正在尝试创建自己的连接 hoc。 App.js 中的构造函数(道具,上下文)正在工作
如果你正在学习redux,不妨学习modern style写reducers
【参考方案1】:
来自docs,这是关于Class.contextType
的内容:
可以为类的
contextType
属性分配一个上下文对象 由React.createContext()
创建。使用此属性可以让您 使用该上下文类型的最接近的当前值this.context
。您可以在任何生命周期方法中引用它 包括渲染功能。
在您的情况下,您似乎只是缺少使用 context
道具将自定义 StoreContext
传递给 redux Provider
您需要执行以下操作:
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
【讨论】:
感谢您的回答。我遇到了同样的问题,并通过在与应用 Provider 的根组件相同的文件上创建存储来解决。示例代码如下:
<Provider store=createStore(reducers)>
<App />
</Provider>
【讨论】:
以上是关于× TypeError: Cannot read properties of undefined (reading 'getState')的主要内容,如果未能解决你的问题,请参考以下文章
TypeError: Cannot read properties of undefined (reading 'app') (Flutter web app)
TypeError: Cannot read properties of undefined (reading 'length') - 想要解释为啥代码这样说
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'fingerprint') Laravel Live
D3.js 一直遇到这个错误 TypeError: Cannot read properties of null (reading 'ownerDocument')?
React Material UI:Appbar 给出了 TypeError: Cannot read properties of undefined (reading '100')
TypeError: Cannot read property 'scrollIntoView' of null 如何解决?