首页 > 解决方案 > 如何使用 redux 更新全局状态并从全局状态中删除项目

问题描述

我正在尝试学习 redux,但我被困在如何正确使用deleteCar我在行动中的概念上。reducer 运行良好,但问题在于 的全局状态cars,如何更新 Car 组件中汽车的状态,然后调用deleteCar函数并修改cars. 当我在组件中打印汽车状态时Car,它是空的。

我有一个名为 Cars 的组件,它是 Car 的父组件(单车)

import React from "react";
import Car from "../Car";
import { connect } from "react-redux";

class Cars extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cars: []
    };
  }
  componentDidMount() {
    fetch(url)
      .then(response => response.json())
      .then(data => this.setState({ cars: data }));
  }
  render() {
    const { cars } = this.state;
    return (
      <div>
        {cars.map(c => (
          <Car key={c.id} make={c.make} price={c.price} id={c.id} />
        ))}
      </div>
    );
  }
}

const mapStateToProps = reduxStoreState => {
  return {
    cars: reduxStoreState.cars
  };
};

export default connect(mapStateToProps)(Cars);

单车

import React from "react";
import { deleteCar } from "../../actions/delete";
import { connect } from "react-redux";

const Car = ({ deleteCar, make, price, id }) => {
  return (
    <div className="card m-4">
      <div className="row">
        <div className="col">
          <h3>{make}</h3>
          <p>{price}</p>
        </div>
      </div>
      <div className="row">
        <button
          className="btn btn-danger"
          onClick={() =>
            deleteCar({
              id: id,
              make: make,
              price: price
            })
          }
        >
          Delete Car
        </button>
      </div>
    </div>
  );
};
const mapStateToProps = reduxStoreState => {
  return {
    cars: reduxStoreState.cars
  };
};

export default connect(mapStateToProps, { deleteCar })(Car);

行动

import { DELETE } from "../constants";
export const deleteCar = (payload) => {
  return {
    type: DELETE,
    payload: payload
  };
};

减速器

import { ADD, DELETE, EDIT } from "../constants";

export default function(state = { cars: [] }, action) {
  switch (action.type) {
    case ADD:
      return {
        ...state,
        cars: [...state.cars, action.payload]
      };
    case DELETE:
      return {
        ...state,
        cars: state.cars.filter(obj => obj !== action.payload)
      };
    case EDIT:
      return {
        ...state,
        cars: action.payload
      };
    default:
      return state;
  }
}

标签: javascriptreactjsreduxreact-redux

解决方案


下面的代码不会像你期望的那样工作:

cars: state.cars.filter(obj => obj !== action.payload)

在 JavaScript 中,对象作为引用存储在变量中。通过像这样调用删除操作:

deleteCar({
  id: id,
  make: make,
  price: price
})

您每次都在创建一个新对象,因此它们永远不会匹配并且不会被过滤。

看起来好像比较是这样的:

{ id: id, make: make, price: price } === { id: id, make: make, price: price }

但实际上,它的比较更像是这样的:

// Both objects contain the same values
// But will not evaluate as equal because the references are different
'object_reference_1' === 'object_reference_2'

相反,我建议id这样检查:

cars: state.cars.filter(obj => obj.id !== action.payload.id)

第二个问题是您在Cars.

不使用本地状态,而是调度一个操作来填充 redux。它可能看起来像这样:

componentDidMount() {
  fetch(url)
  .then(response => response.json())
  // Or preferably create a new action and call it like you did `deleteCar`
  .then(data => this.props.dispatch({ type: 'INITIALIZE', cars: data }));
}

然后在减速器中添加这种情况:

switch (action.type) {
  case 'INITIALIZE':
    return {
      ...state,
      cars: action.payload
    };

确保删除本地状态cars并替换const { cars } = this.state;为使用this.props.


推荐阅读