mapStateToProps()在Redux app嵌套状态下的状态?

时间:2016-09-26 06:10:46

标签: javascript reactjs redux state

我试图找出为什么我在状态下获取和存储的JSON数据没有被映射到我的组件道具,但是在console.log()编辑时出现了来自mapStateToProps()函数。我做错了什么,我没有在这里看到?

编辑:显然,状态属性正在映射到组件,但是是嵌套的。从data内部登录时,mapStateToProps()属性必须通过state.state.data进行访问。在此之前(请参阅reducer),记录action.data时,数据将按预期显示。没有奇怪的筑巢。 也许connect函数有问题吗?

查看状态对象中是否填充了州属性:

See the data property populated within the state object

以下是我的组件:

class ViewSelector extends Component {
  componentWillMount() {
    this.props.fetchDataAsync('VIEW ALL');
  }

  selectView(event) {
    // this.props.data comes up undefined despite state being mapped
    // to the component props
    console.log('props: ' + this.props.data);
    this.props.filterData(event.target.innerHTML, this.props.data);
  }

  render() {
    return (
      <section>
        <nav>
          <button onClick={this.selectView.bind(this)}>VIEW ALL</button>
          <button onClick={this.selectView.bind(this)}>VIEW LAST WEEK</button>
          <button onClick={this.selectView.bind(this)}>VIEW LAST MONTH</button>
        </nav>
        <Dashboard data={this.props.data}/>
      </section>
    );
  }
}

function mapStateToProps(state) {
  console.log(state);
  // this console.log shows the state with the data property.
  return {
    data: state.data
  };
}

export default connect(mapStateToProps, actions)(ViewSelector);

编辑:这是澄清的减速器:

import {
  FETCH_DATA,
  FETCH_DATA_SUCCESS,
  FETCH_DATA_FAILURE,
  FILTER_DATA
} from '../actions/types';
import { getLastWeek, getLastMonth } from './reducer_helper';

const initialState = {
  error: '',
  loading: false,
  data: []
};

/* eslint-disable */
const app = (state = initialState, action) => {
  switch(action.type) {
    case FETCH_DATA:
      return { ...state, error: '', loading: true };
    case FETCH_DATA_SUCCESS:
      // console.log(action.data) returns data as expected.
      // no nesting...until it hits the mapStateToProps() function
      return { ...state, error: '', loading: false, data: action.data };
    case FETCH_DATA_FAILURE:
      return { ...state, error: action.error, loading: false };
    case FILTER_DATA:
      let data;
      if (action.view === 'VIEW LAST WEEK') {
        data = getLastWeek(state.data);
      } else if (action.view === 'VIEW LAST MONTH') {
        data = getLastMonth(state.data);
      } else {
        data = state.data;
      }
      return { ...state, error: '', loading: false, data };
  }
  return state;
}

export default app;

行动创作者澄清对减速机的调度:

export function fetchData() {
  return {
    type: FETCH_DATA
  };
}

export function fetchDataSuccess(data) {
  return {
    type: FETCH_DATA_SUCCESS,
    data: data
  };
}

export function fetchDataFailure(data) {
  return {
    type: FETCH_DATA_FAILURE,
    data
  };
}

export function filterData(view) {
  return {
    type: FILTER_DATA,
    view
  };
}

export function fetchDataAsync() {
  return dispatch => {
    dispatch(fetchData());

    axios.get(DATA_URL)
    .then(res => {
      dispatch(fetchDataSuccess(res.data));
    }).catch(err => {
      dispatch(fetchDataFailure(err));
    });
  };
}

整个应用程序的呈现方式&amp; Redux商店:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import App from './components/app';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>
  , document.querySelector('.container'));

3 个答案:

答案 0 :(得分:7)

经过多次审查,调试并询问其他开发人员,简而言之,这就是我遇到的问题:减速器以及如何将其导入主“清单”文件以管理所有其他减速器。

基本上,因为我在这个项目中只使用一个reducer ,所以不需要一个manifest reducer文件。见下文:

import { combineReducers } from 'redux';
import Reducer from './reducer';

const rootReducer = combineReducers({
  state: Reducer
});

export default rootReducer;

我不知道为什么这是嵌套状态。也许是因为,从理论上讲,我们将处理具有不同目的的多个reducer(如数据缩减器和用户缩减器),并且需要将它们嵌套到我们的状态树中进行管理。

state = {
  // here is one nested reducer with its own properties
  data: {
    type: // somevalue,
    filtered: true
  },
  // here is another
  user: {
    name: // somename,
    password: // somepassword
  }
};

简而言之......请注意您的减速器如何导入createStore功能,以及是否使用减速器,或者是否有多个减速器通过清单运行文件。

干杯。

答案 1 :(得分:5)

因此mapStateToProps的{​​{1}}值正在返回一个对象。你可能想要这个:

data

这样您就可以访问function mapStateToProps(state) { console.log(state); // this console.log shows the state with the data property. return { ...state.app }; } 缩减器中的字段。此外,从示例中还不清楚您将如何使用数据,或者包含哪些字段。此外,首先,您的reducer不会初始化为null或将使用的字段为空值,这肯定会导致错误。可能最好从data对象开始:

initialState

答案 2 :(得分:0)

我在mapStateToProps中遇到了类似的问题,在第一个渲染中,它将使用状态键将初始状态嵌套在对象中。当我使用调度方法更新状态时,它将创建另一个键值对。 (控制台中的以下条目是我在mapStateToProps函数中控制台日志状态时的情况。)

嵌套的初始状态:
initial State which is nested

我发布了在我的reducer函数中,我正在返回默认案例的状态。

const initialState = {
    stateprop1: false,
    user_text: "empty",
    };

    const reducer1 = (state = initialState, action)             => {
    switch (action.type) {
        case ACTION_TYPES.SUCCESS:
            return {
                ...state,
                stateprop1: true,
            };
        case ACTION_TYPES.FAILURE:
            return {
                ...state,
                stateprop1: false,
            };
        case ACTION_TYPES.USER_INPUT:
            return {
                ...state,
                user_text: action.payload,
            };
        default:
            return {
                state,
            };
    }
};

如果改为在默认情况下传播状态,则不会观察到嵌套行为。

default:
    return {
        ...state,
    };

现在,如果我在mapStateToProps函数中控制日志状态,我将得到

未嵌套的状态:
state that isn't nested

我希望这会有所帮助。