Tyler Zika Tyler Zika - 4 years ago 173
React JSX Question

Update a component list after deleting record

I have a component. It displays a list of records. You can click the delete icon, and as soon as you go to a different page and return to the list, the record is no longer there. How do I remove the record from the list without going to a different page?

I've tried using

componentWillUpdate()
and
componentDidUpdate()
and placing my
getTerritoryGeographies(this.props.params.id)
in those functions, but those functions keep calling the data and do not stop. I'm restricted to API limits.

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


UPDATE: I figured out how do remove it by updating my
onDeleteClick()
, but it seems unnecessarily heavy for a react app. Thoughts?

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

Answer Source

Please post your action and reducer so that we can see what you are doing on the Redux side.

If you are renderings a list from data that is in the Redux store, you can use React-Redux's connect Higher Order Function to wrap the component, thus enabling access to the store as component props. So that part looks correct.

When you are firing the action creator, you should be passing in the id of the data that you would like deleted, and in your reducer, something like this: case 'DELETE_TERRITORY': const territoryId = action.data; return state.filter(territory => territory.id !== territoryId);

When the reducer returns the new, filtered array, your component should update with the list minus the territory you just deleted.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download