无法从Redux商店读取状态。我错过了什么?

时间:2022-08-22 21:51:36

Here is my index.js where I initially dispatch an action to read my list of locations:

这是我的index.js,我最初调度一个动作来读取我的位置列表:

import 'babel-polyfill';
import React from 'react';
import { render } from  'react-dom';
import configureStore from './store/configureStore';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import {loadLocationList} from './actions/locationActions';
import './css/styles.css';

const store = configureStore();

render(
    <Provider store={store}>
        <Router history={browserHistory} routes={routes} />
    </Provider>,
    document.getElementById('app')
);

Then here is my action where I get the data & then create an action out of it:

然后这是我的行动,我获取数据,然后从中创建一个动作:

export function loadLocationListSuccess(alistingData) {
    return { type: types.LOAD_LOCATION_LIST_SUCCESS, listingData: alistingData};
}

export function loadLocationList() {
        return function(dispatch){ //we return a function that accepts a parameter, we just called it dispatch
            //dispatch(fetchCallActions.fetchCallStart("")); // we dispatch a function fetchCallStart to indicate the start of our call, this is to keep in check with our asynchronous function calls
            let link = 'http://example.com:8399/location';//our fetch url
            console.log(link); //we log our link, just for debug purposes

            return fetch(link) //start fetch
            .then(function(response) {
                return response.json();
            }).then(function(json) {
                dispatch(loadLocationListSuccess(json));
            }).catch(function(ex) {
                console.log('parsing failed', ex);

            });
        };
    }

Then here is my reducer:

然后这是我的减速机:

import * as types from '../actions/actionTypes';

export default function locationReducer(state = [], action) {
    switch(action.type) {
        case types.LOAD_LOCATION_LIST_SUCCESS:
            return {listingData: action.listingData};
        default:
            return state;
    }
}

Then here is my mapStateToProps & connect function:

那么这是我的mapStateToProps&connect函数:

    function mapStateToProps(state, ownProps) {
      return {
        // we'll call this in our component -> this.props.listingData
        listingData: state.listingData
      };
    }

export default connect(mapStateToProps, mapDispatchToProps)(homePage);

For some reason, it cannot read state.listingData or am I actually doing it wrongly? Anyone can help me with this problem?

由于某种原因,它无法读取state.listingData或我实际上做错了吗?任何人都可以帮我解决这个问题?

I tried logging state.listingData and it showed undefined

我尝试记录state.listingData并显示未定义

Here is my configureStore:

这是我的configureStore:

import {createStore, applyMiddleware} from 'redux';
import rootReducer from '../reducers';
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from 'redux-thunk';

export default function configureStore(initialState) {
    return createStore(
        rootReducer,
        initialState,
        applyMiddleware(thunk, reduxImmutableStateInvariant())
    );
}

Here is my combined Reducer:

这是我的组合减速器:

import {combineReducers} from 'redux';
import courses from './courseReducer';
import locations from './locationReducer';

const rootReducer = combineReducers({
    courses,
    locations
});


export default rootReducer;

Did I not connect it to the store properly?

我没有正确连接到商店吗?

Recent update: Logging JSON.stringify(state) in mapStateToProps would actually shows the result. Thanks guys.

最近更新:在mapStateToProps中记录JSON.stringify(state)实际上会显示结果。多谢你们。

The correct path turned out to be state.locations.listingData because I think in my combined Reducer I included the reducer as locations so maybe thats why the state for it is state.locations. Hope this helps anyone with the problem.

正确的路径原来是state.locations.listingData,因为我认为在我的组合Reducer中我将reducer包含为位置所以也许这就是为什么它的状态是state.locations。希望这有助于解决问题的任何人。

1 个解决方案

#1


2  

  • Can you show the code of configureStore file? The problem might be there, may be you forgot to add reducer to list of reducers.
  • 你能展示configureStore文件的代码吗?可能存在问题,可能是您忘记将reducer添加到reducer列表中。

  • Does the action works right? Did you log data before dispatch(loadLocationListSuccess(json));?
  • 行动是否正常?你在调度之前是否记录了数据(loadLocationListSuccess(json));?

UPD:

Because of rootReducer. Each reducer creates their own key in store. When you combine your reducers in rootReducer, like:

因为rootReducer。每个reducer都会在商店中创建自己的密钥。在rootReducer中组合reducers时,如:

import locations from './locationReducer';
const rootReducer = combineReducers({
    courses,
    locations
});

It creates store with this kind of structure:

它用这种结构创建商店:

const store = {
    courses: {},
    locations: {}
}

So, after that you dispatched action and reducer changed the data to this:

所以,之后您调度了action并且reducer将数据更改为:

const store = {
    courses: {},
    locations: {
       listingData: someData
    }
}

If you want to access to listingData like: state.listingData, you need to change a little your reducer and combineReducer to:

如果要访问listingData,如:state.listingData,则需要将reducer和combineReducer更改为:

export default function listingData(state = {}, action) {
    switch(action.type) {
        case types.LOAD_LOCATION_LIST_SUCCESS:
            return action.listingData;
        default:
            return state;
    }
}

...

import listingData from './locationReducer';
const rootReducer = combineReducers({
    courses,
    listingData
});

#1


2  

  • Can you show the code of configureStore file? The problem might be there, may be you forgot to add reducer to list of reducers.
  • 你能展示configureStore文件的代码吗?可能存在问题,可能是您忘记将reducer添加到reducer列表中。

  • Does the action works right? Did you log data before dispatch(loadLocationListSuccess(json));?
  • 行动是否正常?你在调度之前是否记录了数据(loadLocationListSuccess(json));?

UPD:

Because of rootReducer. Each reducer creates their own key in store. When you combine your reducers in rootReducer, like:

因为rootReducer。每个reducer都会在商店中创建自己的密钥。在rootReducer中组合reducers时,如:

import locations from './locationReducer';
const rootReducer = combineReducers({
    courses,
    locations
});

It creates store with this kind of structure:

它用这种结构创建商店:

const store = {
    courses: {},
    locations: {}
}

So, after that you dispatched action and reducer changed the data to this:

所以,之后您调度了action并且reducer将数据更改为:

const store = {
    courses: {},
    locations: {
       listingData: someData
    }
}

If you want to access to listingData like: state.listingData, you need to change a little your reducer and combineReducer to:

如果要访问listingData,如:state.listingData,则需要将reducer和combineReducer更改为:

export default function listingData(state = {}, action) {
    switch(action.type) {
        case types.LOAD_LOCATION_LIST_SUCCESS:
            return action.listingData;
        default:
            return state;
    }
}

...

import listingData from './locationReducer';
const rootReducer = combineReducers({
    courses,
    listingData
});