我正在开展一个项目,涉及使用打字稿/ react / redux和黄金布局。我在使用Redux的Provider Store处理反应方面遇到了一些问题。我做了一些以前的搜索,并遇到了以下问题:
How to use Redux's Provider with React
我一直在关注该问题的答案中给出的建议,编写我自己的代码,如下所示:
import React from 'react';
import GoldenLayout from 'golden-layout';
import {Provider} from 'react-redux';
import Default from '../modules/m-Default/Default';
import PropTypes from 'prop-types';
interface GoldenLayoutWrapperProps {}
interface GoldenLayoutWrapperState {}
class GoldenLayoutWrapper extends React.Component <GoldenLayoutWrapperProps, GoldenLayoutWrapperState> {
public layout;
static contextTypes = {
store: PropTypes.object.isRequired
};
private wrapComponent(Component, store) {
class Wrapped extends React.Component {
render () {
return (
<Provider store={store}>
<Component {...this.props}/>
</Provider>
)
}
}
return Wrapped;
}
componentDidMount() {
var layout = new GoldenLayout(this.layoutConfig, this.layout);
layout.registerComponent('Default', this.wrapComponent(Default, this.context.store));
}
render() {
return (
<div className="golden-layout-wrapper" ref={input => this.layout = input}/>
)
}
private layoutConfig = {}
}
export default GoldenLayoutWrapper;
你可以看到,基本上我的班级正在做的是通过注册具有黄金布局的反应组件来设置黄金布局界面。因此,这适用于redux,我已经定义了wrapComponent
函数来返回要注册的react组件,但是包装在Redux Provider中。
我按照上面链接的问题中列出的模式,使用context.store
和store: PropTypes.object.isRequired
但是,当我运行应用程序时,我从浏览器控制台收到以下错误:
Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.
在此下,在我的浏览器控制台中,我收到错误:
Uncaught TypeError: Cannot read property 'object' of undefined at new GoldenLayoutWrapper
仍然是Redux的新手,我不是百分之百确定这意味着什么,但在我看来store
未定义,因此没有有效的reducer。但是,根据我上面提到的问题,这应该有效。
这可能是什么问题?
这是我的root应用程序和root reducer的代码:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Store, createStore } from 'redux';
import { Provider } from 'react-redux';
import GoldenlayoutWrapper from './main/GoldenLayoutWrapper';
import rootReducer from './main/rootReducer';
const initialState = {};
const store: Store<any> = createStore(rootReducer, initialState);
ReactDOM.render(
<Provider store={store}>
<GoldenlayoutWrapper/>
</Provider>,
document.getElementById('root')
);
我已将rootReducers留空,以便将来的开发人员可以将代码添加到其中:
import { combineReducers } from 'redux';
// Import your reducers here
const rootReducer = combineReducers({
// Add your reducers here
});
export default rootReducer;
我也尝试了以下内容:
在我的根应用中,将商店定义为const store:<any> = createStore(state=>state, initialState)
而不是const store:<any> = createStore(rootReducer, initialState)
在我的root reducer中,尝试指定一个空白的reducer:blank: function(state, action) {if (state == null) state = [] return state;}
但这些都没有奏效。我得到了与上面相同的错误。
答案 0 :(得分:1)
以下是Redux
的基本用法,看看您的代码是否包含所有必需的成分:
import { createStore, combineReducers } from 'redux';
// ACTIONS
const SAMPLE_ACTION_TYPE = 'gd:SAMPLE_ACTION_TYPE';
const sampleAction = (payload) => ({
type: SAMPLE_ACTION_TYPE,
payload
});
// REDUCER
const sampleReducer = (state={}, action) => {
return state;
};
const sampleTwoReducer = (state=[],action) => {
return state;
}
// STORE
const store = createStore(
combineReducers({
sample:sampleReducer,
sampleTwo:sampleTwoReducer
})
);
// SUBSCRIBE
store.subscribe(() => {
console.log("STORE STATE", store.getState());
});
// DISPATCH SOME ACTIONS
store.dispatch(sampleAction());
上面创建以下输出:
STORE STATE
{sample: {…}, sampleTwo: Array(0)}
sample:
__proto__:Object
sampleTwo:Array(0) length:0
__proto__:Array(0)
__proto__:Object
但将代码更改为:
// STORE
const store = createStore(
combineReducers({
sample:null,
sampleTwo:null
})
);
产生相同的错误,检查传递给combineReducer
**编辑**
要为组件提供商店,您需要做两件事,首先设置Provider
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
ReactDOM.render(
<Provider store={store}>
<MyApp />
</Provider >, document.getElementById('app'));
然后在您的组件中调用高阶函数connect
这会将您的组件连接到商店,the docs
import { connect } from 'react-redux';
import React from 'react';
class MyComponent extends React.Component {
notMapped = (payload) => {
this.props.dispatch(sampleAction(payload));
}
render() {
const {sample, mappedFunction} = this.props;
return (
<div>
<p>{sample}</p>
<button onClick={() => {
mappedFunction("test");
}}>Call mapped Function</button>
<button onClick={() => {
this.notMapped("test");
}}>Call NOT mapped Function</button>
</div>
);
}
}
const mapDispatchToProps = (dispatch) => ({
mappedFunction: (payload) => dispatch(sampleAction(payload))
});
const mapStateToProps = (state) => ({
sample: state.sample
});
export default connect(mapStateToProps,mapDispatchToProps)(MyComponent);// connect