删除记录后更新组件列表

Update a component list after deleting record

我有一个组件。它显示记录列表。您可以单击删除图标,一旦转到其他页面并 return 到列表,记录就不再存在。如何在不转到其他页面的情况下从列表中删除记录?

我试过使用 componentWillUpdate()componentDidUpdate() 并将我的 getTerritoryGeographies(this.props.params.id) 放在这些函数中,但是这些函数一直在调用数据并且不会停止。我受限于 API 限制。

import React, { Component, PropTypes} from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';

import { getTerritoryGeographies, deleteTerritoryGeography } from '../actions/index';

import TerritoryTabs from './territory-tabs';

class TerritoryGeographyList extends Component {

  componentWillMount() {
    //console.log('this is the child props (TerritoryGeographyList)');
    console.log(this.props);
    this.props.getTerritoryGeographies(this.props.params.id);
  }

  componentDidMount() {
    console.log('componentDidMount');
  }

  componentWillUpdate() {
    console.log('componentWillUpdate');
    this.props.getTerritoryGeographies(this.props.params.id);
  }

  componentDidUpdate() {
    console.log('componentDidUpdate');
  }

  onDeleteClick(id) {
    this.props.deleteTerritoryGeography(id);

  }

  static contextTypes = {
    router: PropTypes.object
  }

  renderTerritoryGeographyList() {
      return this.props.territoryGeographies.map((geography) => {
        return (
          <tr key={geography.Id}>
              <th scope="row" data-label="Country">
                <div className="slds-truncate">{geography.tpslead__Country__c}</div>
              </th>
              <td data-label="State/Provice">
                <div className="slds-truncate">{geography.tpslead__State__c}</div>
              </td>
              <td data-label="Postal Start">
                <div className="slds-truncate">{geography.tpslead__Zip_Start__c}</div>
              </td>
              <td data-label="Postal End">
                <div className="slds-truncate">{geography.tpslead__Zip_End__c}</div>
              </td>
              <td className="slds-text-align--right" data-label="Action">
                <button className="slds-button slds-button--icon" title="edit">
                      <svg className="slds-button__icon" aria-hidden="true">
                        <use xlinkHref={editIcon}></use>
                      </svg>
                      <span className="slds-assistive-text">Edit</span>
                    </button>
                    <button onClick={() => this.onDeleteClick(geography.Id)} className="slds-button slds-button--icon" title="delete" data-aljs="modal" data-aljs-show="PromptConfirmDelete">
                      <svg className="slds-button__icon" aria-hidden="true">
                        <use xlinkHref={deleteIcon}></use>
                      </svg>
                      <span className="slds-assistive-text">Delete</span>
                    </button>
              </td>
            </tr>
        );
      });
  }

  render() {
    return (
    <TerritoryTabs id={this.props.params.id} listTab="geography">
          <Link to={"territory/" + this.props.params.id + "/geography/new"} className="slds-button slds-button--brand">
            Add New Geography
          </Link>
          <table className="slds-table slds-table--bordered slds-table--cell-buffer slds-m-top--large">
              <thead>
                <tr className="slds-text-title--caps">
                  <th scope="col">
                    <div className="slds-truncate" title="Country">Country</div>
                  </th>
                  <th scope="col">
                    <div className="slds-truncate" title="State/Provice">State/Provice</div>
                  </th>
                  <th scope="col">
                    <div className="slds-truncate" title="Postal Start">Postal Start</div>
                  </th>
                  <th scope="col">
                    <div className="slds-truncate" title="Postal End">Postal End</div>
                  </th>
                  <th className="slds-text-align--right" scope="col">
                    <div className="slds-truncate" title="Action">Action</div>
                  </th>
                </tr>
              </thead>
              <tbody>
            {this.renderTerritoryGeographyList()}
              </tbody>
            </table>
    </TerritoryTabs>
    );
  }
}

function mapStateToProps(state) {
  //console.log(state);
  return { territoryGeographies: state.territoryGeographies.all
        };
}

export default connect(mapStateToProps, { getTerritoryGeographies, deleteTerritoryGeography })(TerritoryGeographyList);

更新:我想出了如何通过更新我的 onDeleteClick() 来删除它,但对于 React 应用程序来说它似乎不必要地沉重。想法?

  onDeleteClick(id) {
    this.props.deleteTerritoryGeography(id);
    var geographyIndex = this.props.territoryGeographies.findIndex(x => x.Id==id)
    this.setState(state => {
                this.props.territoryGeographies.splice(geographyIndex, 1);
                return {territoryGeographies: this.props.territoryGeographies};
            });
  }

请 post 你的 action 和 reducer 以便我们可以看到你在 Redux 端做了什么。

如果您从 Redux 存储中的数据渲染列表,您可以使用 React-Redux 的 connect 高阶函数来包装组件,从而允许访问存储组件道具。所以那部分看起来是正确的。

当你触发 action creator 时,你应该传入你想要删除的数据的 id,在你的 reducer 中,像这样: case 'DELETE_TERRITORY': const territoryId = action.data; return state.filter(territory => territory.id !== territoryId);

当 reducer returns 新的、过滤后的数组时,您的组件应该更新为列表减去您刚刚删除的区域。

这段代码控制是否正确执行删除操作。 Returns如果删除操作失败则状态为第一个状态

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

    handleDelete = async productId => {

        const originalProducts = this.state.products;
        const products = this.state.products.filter(p => productId !== p.productId);
        this.setState({ products });

        try {
            const result = await deleteProduct(productId);
            if (result.status === 200) {
                // codes goes here. for example send notification
            }
        }
        catch (ex) {
            if (ex.response && ex.response.status === 404) {
                // codes goes here. for example send notification
            }

            this.setState({ products: originalProducts });
        }
    }

反应