删除记录后更新组件列表

时间:2017-02-07 00:51:23

标签: reactjs redux react-redux

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

我尝试使用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()来删除它,但对于反应应用程序来说似乎不必要。想法?

  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};
            });
  }

enter image description here

2 个答案:

答案 0 :(得分:1)

请发布你的行动和减速器,以便我们可以看到你在Redux方面做了什么。

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

当你解雇动作创建者时,你应该传递你想删除的数据的id,并在你的reducer中传递这样的东西: case 'DELETE_TERRITORY': const territoryId = action.data; return state.filter(territory => territory.id !== territoryId);

当reducer返回新的已过滤数组时,您的组件应使用列表减去刚删除的区域进行更新。

答案 1 :(得分:-1)

此代码控制删除操作是否正确执行。如果删除操作失败,则将状态返回到第一个状态

<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 });
        }
    }

reactjs