【问题标题】:Using Redux Provider Store with Reactjs - error Store does not have a valid reducer将 Redux Provider Store 与 Reactjs 一起使用 - 错误 Store 没有有效的 reducer
【发布时间】:2018-02-22 23:43:25
【问题描述】:

我正在着手一个项目,该项目涉及使用 typescript/react/redux 和黄金布局。我在让 Redux 的 Provider Store 与 react 一起工作时遇到了一些问题。我之前做了一些搜索,遇到了以下问题:

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;

您可以看到,基本上我的班级正在做的,是通过将 react 组件注册到黄金布局来设置黄金布局界面。为了与 redux 一起工作,我定义了 wrapComponent 函数来返回要注册的反应组件,但包装在 Redux Provider 中。

我遵循上面链接的问题中概述的模式,使用 context.storestore: 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 的新手,我不能 100% 确定这意味着什么,但在我看来 store 是未定义的,因此没有有效的 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;

我还尝试了以下方法:

在我的根应用中,将 store 定义为 const store:&lt;any&gt; = createStore(state=&gt;state, initialState) 而不是 const store:&lt;any&gt; = createStore(rootReducer, initialState)

在我的根减速器中,尝试指定一个空白减速器:blank: function(state, action) {if (state == null) state = [] return state;}

但这些都不起作用。我得到了和上面一样的错误。

【问题讨论】:

  • 你的商店怎么样?它是您定义的还是您认为它应该来自提供给您的某个地方?:)
  • 添加您调用createStore的代码。该错误意味着在创建商店时您没有为其提供减速器。
  • @Lukasz'Severiaan'Grela 我已经用这些信息编辑了我的帖子
  • @trixn 我已经添加了该信息

标签: reactjs redux react-redux


【解决方案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

【讨论】:

  • 商店如何传递给组件和提供者?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 2019-09-05
  • 2018-04-27
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
相关资源
最近更新 更多