删除记录后更新组件列表
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 });
}
}
反应
我有一个组件。它显示记录列表。您可以单击删除图标,一旦转到其他页面并 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 });
}
}