【问题标题】:redux-immutable mapStateToProps props emptyredux-immutable mapStateToProps 道具为空
【发布时间】:2018-01-25 00:08:22
【问题描述】:

我正在更新我的第一个 react/redux 应用程序以使用 redux-immutable 并且无法弄清楚为什么 mapStateToProps 中的道具是空的。我看到 thunk 记录器输出中填充了属性,但它们在组件中为空。

components/Packages.jsx:

import React from 'react';
import pureRender from 'pure-render-decorator';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {loadPackages} from '../../actions/packageActions';
import PackageList from './PackageList';
import ImmutablePropTypes from 'react-immutable-proptypes';
import {Map,fromJS,List} from 'immutable';

export class Packages extends React.Component {
  constructor(props, context) {
    super(props, context);
  }
  componentDidMount() {
    this.props.dispatch(loadPackages());
  }
  render() {
    return (
      <div className="col-lg-12">
        {this.props.results.length ?
        <PackageList results={this.props.results} /> :
        <h3>No Packages Available</h3>}
      </div>
    );
  }
};

Packages.propTypes = {
  results: ImmutablePropTypes.list.isRequired,
};

const mapStateToProps = (state, ownProps) => {
  return {
    packages: state.get('packages'),
    results: !state.getIn(['packages','results']) ? List() : state.getIn(['packages','results'])
  };
}

export const PackagesContainer = connect(mapStateToProps)(Packages);

actions/packageActions.jsx:

import * as types from './actionTypes';
import PackageApi from '../api/packageApi';

export function loadPackages() {
  return function(dispatch) {
    return PackageApi.getAllPackages().then(packages => {
      dispatch(loadPackagesSuccess(packages));
    }).catch(error => {
      throw(error);
    });
  };
}

export function loadPackagesSuccess(packages) {
  return {
    type: types.LOAD_PACKAGES_SUCCESS,
    state: packages.data
  }
}

reducers/packageReducer.js:

import {Map,fromJS,List} from 'immutable';
import * as types from '../actions/actionTypes';
import initialState from './initialState';

export default function packageReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOAD_PACKAGES_SUCCESS:
      return state.set('packages', fromJS(action.state));
    default:
      return state;
  }
}

reducers/initialState.js:

import {Map, List} from 'immutable';
import update from 'immutability-helper';

const initialState = Map({
  packages: Map({
    totalCount: null,
    results: List(),
    dir: null,
    totalPages: null,
    limit: null,
    sort: null,
    page: null
  })
});
    
export default initialState;

reducers/rootReducer.js:

import {combineReducers} from 'redux-immutable';
import packages from './packageReducer';
import login from './loginReducer';
import { reducer as form } from 'redux-form/immutable';

const reducer = combineReducers({
  packages,
  login,
  form
});

export default reducer;

store.js:

import {createStore, applyMiddleware} from 'redux';
import {createLogger} from 'redux-logger';
import reducer from './reducers/rootReducer';
import thunk from 'redux-thunk';
import initialState from './reducers/initialState';

const store = createStore(reducer, initialState, applyMiddleware(thunk, createLogger()));

export default store;

thunk log:

state:{
  results: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
  type: "LOAD_PACKAGES_SUCCESS"
}

编辑

Redux DevTools 显示正确的数据结构,但 mapStateToProps 仍然返回空列表。

Redux 开发工具:

{
packages
packages{
  "totalCount": 145,
  "results": [
    {

Packages.jsx:

const mapStateToProps = (state, ownProps) => {
  return {
    packages: state.get('packages'),
    results: !state.getIn(['packages','packages','results']) ? List() : state.getIn(['packages','packages','results'])
  };
}

我更新了initialState,它解决了state.getIn(['packages','results']);undefined 的问题。但是,结果属性仍然会生成一个空列表。

【问题讨论】:

  • 您是否检查以确保LOAD_PACKAGES_SUCCESS 操作正确更新了商店? Packages 组件是否从默认(未命名)导出中导入,以确保它包含在 connect 中?
  • 如何验证 LOAD_PACKAGES_SUCCESS 操作是否正确更新了商店? PackagesContainer 在 index.jsx 中被导入为import {PackagesContainer} from './components/Package/Packages';
  • 您可以使用 Chrome 的 Redux DevTools 扩展程序来查看您的 Redux 存储在所有调度操作之前和之后的状态。
  • 您必须将组合减速器(即“packages”名称)传递给 state.get,例如 packages:state.get(“packages”, “packages”);在你的 mapStateToProps 中。这里 state.get 的第一个参数是您在组合减速器中定义的包名称,第二个参数是您在包减速器中设置的。您必须像这样传递才能获取组件中的数据。

标签: reactjs redux redux-immutable


【解决方案1】:

我可以看到的问题是您在组件中执行 state.get 时没有传递组合减速器名称,即包。

传递包将减速器名称组合到 state.get 或 state.getIn 方法中,作为组件中的第一个参数。

要从 mapStateToProps 中的状态获取包,然后获取如下状态

  packages: state.get(“packages”,”packages”); //here first param is your packages combine reducer name

这也适用于 state.getIn。每当您组合减速器时,您必须将组合减速器名称作为第一个参数传递给 state.get 或 state.getIn。

我希望这能解决您的问题。

【讨论】:

  • 控制台输出显示state.getIn(['packages','packages'])未定义我是否需要在reducerreturn state.set('packages', action.state);//Map(action.state)中将响应对象转换为Map()? state.set 是否应该将普通对象转换为 Map()?
【解决方案2】:

改变:

return state.set('packages', action.state);

return state.set('packages', fromJS(action.state));

LOAD_PACKAGE_SUCCESS.

【讨论】:

    猜你喜欢
    • 2019-08-01
    • 2018-02-03
    • 2020-07-15
    • 2019-10-03
    • 2019-09-20
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多