【问题标题】:How to properly update props in redux store?如何正确更新 redux 商店中的道具?
【发布时间】:2020-10-18 21:29:32
【问题描述】:

我有一个带有购物车组件的 React 应用程序。当单击项目中的“添加到购物车”按钮时,我使用 Redux 更新购物车。 问题是,即使我更新了 item 组件中的 props,props 也不会同时更新。 当我在 Chrom 开发者工具组件选项卡中检查组件中的 props 时,我可以看到只有当我导航到另一个组件时,道具才会更新。 但是,购物车组件永远不会收到更新的道具来填充购物车项目。这些是必要的组件。

物品组件

import React, { Component } from 'react';
import ProductData from './DataSet/ProductData';
import { compose } from 'recompose';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { updateCartList } from '../../store/actions';

class LatestProducts extends Component {

    addItemToCart = (id) => {
        const { cartList, updateCartList } = this.props;
        var items = cartList;
        ProductData.forEach(each => {
            if (each.id === id) {
                items.push(each)
            }
        });
        updateCartList(items);
    }

    render() {

        return (
            <div>
                <div className="itemGridMain">
                    {
                        ProductData.map(product => {
                            return (
                                <div className="itemCard" key={product.id}>
                                    <button onClick={() => this.addItemToCart(product.id)}>Add to cart</button>
                                </div>
                            )
                        })
                    }
                </div>
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        cartList: state.cartList,
    };
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        updateCartList: updateCartList,
    }, dispatch);
}

export default compose(connect(mapStateToProps, mapDispatchToProps))(LatestProducts);

购物车组件

import React, { Component } from 'react';
import { compose } from 'recompose';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { updateCartList } from '../../store/actions';

class FrontHeader extends Component {

    render() {

        const { cartList } = this.props;

        return (
            <div className="cartList">
                {
                    cartList && cartList.length > 0 && cartList.map(item => {
                        return (
                            <div className="listItem" key={item.id}>
                            </div>
                        )
                    })
                }
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        cartList: state.cartList,
    };
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        updateCartList: updateCartList,
    }, dispatch);
}

export default compose(connect(mapStateToProps, mapDispatchToProps))(FrontHeader);

购物车清单缩减器

const cartListReducer = (state = [], action) => {
    switch (action.type) {
        case 'UPDATE_CARTLIST':
            return action.payload;
        default:
            return state;
    }
}

export default cartListReducer;

购物车列表索引

import cartListReducer from './cartlist';
import { combineReducers } from 'redux';

const allReducers = combineReducers({
    cartList: cartListReducer,
})

export default allReducers;

Redux 操作

export const updateCartList = (newCartList) => {
    return {
        type: 'UPDATE_CARTLIST',
        payload: newCartList,
    }
}

我该如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    问题

    this.props.cartList 是您的状态,通过推入该数组并将其保存回状态,您只是在改变状态。

    addItemToCart = (id) => {
        const { cartList, updateCartList } = this.props;
        var items = cartList; // <-- state reference
        ProductData.forEach(each => {
            if (each.id === id) {
                items.push(each) // <-- push into state reference
            }
        });
        updateCartList(items); // <-- saved state reference
    }
    

    解决方案

    您应该为 react 提供一个新的数组对象引用以获取差异,因为协调使用浅对象相等性。

    您的addItemToCart 可能应该只是将您想要添加到购物车的商品并将购物车更新逻辑移动到减速器。

    最新产品

    class LatestProducts extends Component {
    
      addItemToCart = (item) => {
        const { updateCartList } = this.props;
        updateCartList(item); // <-- pass item to action creator
      }
    
      render() {
        return (
          <div>
            <div className="itemGridMain">
              {ProductData.map(product => {
                return (
                  <div className="itemCard" key={product.id}>
                    <button
                      onClick={() => this.addItemToCart(product)} // <-- pass product/item
                    >
                      Add to cart
                    </button>
                  </div>)
                })
              }
            </div>
          </div>
        );
      }
    }
    

    cartListReducer

    const cartListReducer = (state = [], action) => {
      switch (action.type) {
        case 'UPDATE_CARTLIST':
          return [...state, action.payload]; // <-- copy state and appen new item
    
        default:
          return state;
      }
    }
    

    【讨论】:

    • 谢谢,成功了!从来没有注意到reducer应该返回一个新的数组对象引用
    • @DavidJohns 请记住,当状态(即组件状态)或 props 更改(即通过 props 提供的 redux 状态)时,react 组件会重新渲染。如果 prop 对象引用没有改变,则 react 假定值没有改变。
    猜你喜欢
    • 1970-01-01
    • 2019-09-16
    • 2020-08-11
    • 2018-11-29
    • 2020-05-14
    • 2021-02-06
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多