【问题标题】:React Redux: Can't map over state after using combineReducersReact Redux:使用 combineReducers 后无法映射状态
【发布时间】:2019-12-03 17:14:06
【问题描述】:

我是 React/Redux 的新手。

我正在制作简单的购物车。 现在我正在尝试显示本地 json 文件中的数据。 数据的状态如下:{items: data here }。 当我在顶级 reducer 文件上编写 reducer 时,我可以映射这些项目。 但是,如果我使用 combineReducers 它会给我错误提示“this.props.items is undefined: return this.props.items.slice(0, 20).map(item =>”。

如何访问和映射项目?

减速机 #1 cartReducer.js

import data from "../data.json";

const INITIAL_STATE = {
    items: data,
    addedItem: [],
    total: 0
}

const cartReducer = (state = INITIAL_STATE, action) => {
    return state;
}

export default cartReducer;

减速机 #2

import { combineReducers } from 'redux';
import items from './cartReducer';

export default combineReducers({
    items
})

显示项目列表的组件

import React from 'react';
import { connect } from 'react-redux';
import { addToCart } from '../actions';

class ItemList extends React.Component {

    renderList() {
      return this.props.items.slice(0, 20).map(item => {
        return (
          <div className="card" key={item.id}>
                <span className="card-title">{item.name}</span>                
                <p>{item.content}</p>
                <p><b>Price: {item.price}$</b></p>    
          </div>
        )
      })      
    }

    render() {
        return (
          <div>
             {this.renderList()}
           </div>
        )
    }
}

const mapStateToProps = state => {
  return {
    items: state.items
  }
}

const mapDispatchToProps = dispatch => {
  return {
    addToCart: (id) => {
      dispatch(addToCart(id))
    }
  }
}

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

JSON 数据

[
  {
      "id": 201,
      "name": "Nulla",
      "price": 207,
      "subCategoryId": 101,
      "categoryId": 1,
      "rate": 2.44,
      "content": "Culpa sed tenetur incidunt quia veniam sed mollitia exercitationem. Laboriosam reprehenderit laborum pariatur ea rem qui inventore. In asperiores dignissimos temporibus et. Beatae consequatur corrupti nam praesentium.",
      "review": 78,
      "typeVariant": "D",
      "colorVariant": "5",
      "imageUrl": "https://placeholdit.imgix.net/~text?txtsize=55&txt=137x945&w=137&h=945"
    },{
      "id": 202,
      "name": "Corporis",
      "price": 271,
      "subCategoryId": 101,
      "categoryId": 1,
      "rate": 2.18,
      "content": "Nam incidunt blanditiis odio inventore. Nobis voluptatum quibusdam laboriosam a numquam. Delectus sequi ipsa possimus ratione repellendus quibusdam. Molestiae fuga laudantium natus dolorem.",
      "review": 67,
      "typeVariant": "A",
      "colorVariant": "4",
      "imageUrl": "https://dummyimage.com/931x785"
    }
]

【问题讨论】:

  • 尝试debuggerconsole.log(this.props) 作为渲染方法的第一行。似乎您的组件没有收到预期的道具。
  • 当我执行console.log(this.props) 时,它给了我一个包含每个状态的对象,该对象无法映射。为了使用地图,状态似乎必须看起来像return { items: state.items.items }。这会给我一个数组。

标签: reactjs redux react-redux


【解决方案1】:

你必须在调度中传递类型

const mapDispatchToProps = dispatch => {
  return {
    addToCart: id => {
      dispatch({ type: 'name of your type' });
    }
  };
};

然后将条件添加到减速器

const cartReducer = (state = INITIAL_STATE, action) => {
   if(action.type === 'name of your type')
      return state;
}

【讨论】:

  • 看起来 OP 正在使用动作创建器。无论如何,这绝对不是问题
【解决方案2】:

当您使用combineReducers 创建reducer 时,您创建了一个reducer,它将调用传递给它的每个reducer,将它们的结果收集到一个新的状态对象中。每个减速器状态的键将是您在传递给combineReducers 的对象中为相应减速器提供的键。

如果你只使用你的 reducer,你的结果状态会如你所料:

{
    items: Array
    addedItem: Array
    total: number
}
export default combineReducers({
    items
})

是语法糖

export default combineReducers({
    items: items
})

这意味着最终状态将如下所示:

{
    items: {
        items: Array
        addedItem: Array
        total: number
    }
}

因此,您可以使用state.items.items 访问您所在州的items 数组

【讨论】:

  • 这是真的,但是错误提示 this.props.items 未定义,所以似乎还有其他问题。
  • this.props.items 未定义,因为 OP 将 state.items 映射到 items。而不是正确的state.items.items
  • 可以在渲染this.props.items &&之前添加条件
  • 如果state.items未定义,您也无法访问state.items.items。可能是redux没有正确初始化。
  • 我改为返回 { items: state.items.items } 并且它起作用了。现在我了解了糖的语法。非常感谢!
【解决方案3】:

您没有绑定 renderList,这就是未定义 props 的原因。 “This”指的是调用函数(renderList)而不是你的组件。并且该函数没有字段道具,因为它只是一个函数。您必须像这样在构造函数中绑定它: this.renderList= this.renderList.bind(this);或者使用这样的数组函数:const renderList = () => {...}。现在 "this" 指的是组件和 props 将被定义。

【讨论】:

  • 当然,@Phillip 所说的也很重要。
猜你喜欢
  • 2020-12-20
  • 2021-09-12
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 2020-04-14
相关资源
最近更新 更多