我有一个组件,可以根据在搜索框中输入的字词对公司进行过滤,然后根据其帐户是否已激活来再次对它们进行过滤,然后将它们映射到包含几列公司数据的表格中。每个公司的最后一个表格列均包含几个按钮,其中一个是触发模式对话框的删除按钮,然后必须确认删除或从模式中取消删除。
为简洁起见,我将忽略不重要的进出口:
import {searchingFor} from '../../../containers/CompaniesContainer/CompaniesContainer';
const companiesTable = (props) => {
return (
<table className={classes.Table}>
<thead>
<tr>
<th className={classes.First}> </th>
<th onClick={props.sortByName} className={[classes.Second, props.sortingClass].join(' ')}><span>Name</span><img src={downArrow} alt="down-arrow" /></th>
<th onClick={props.sortByAddress} className={[classes.Third, props.sortingClass].join(' ')}><span>Email address</span><img src={downArrow} alt="down-arrow" /></th>
<th onClick={props.sortByAdded} className={[classes.Fourth, props.sortingClass].join(' ')}><span>Added</span><img src={downArrow} alt="down-arrow" /></th>
<th className={classes.Last}> </th>
</tr>
</thead>
<tbody>
{
props.companies.filter(searchingFor(props.term)).filter(function (company) {
if(props.isActive === true) {
return company.active;
} else {
return !company.active
}
}).map((item, index) =>
<tr key={item.id}>
<td>
<img src={companyImg} alt="companies" />
</td>
<td>{item.name}</td>
<td>{item.street},<br/>{item.city}</td>
<td>{item.added}</td>
<td>
<Button btnType={props.btnClass1} onClick={() => props.deleteInitiate(item.name)}>{props.btnText1}</Button>
<Button btnType={props.btnClass2}>{props.btnText2}</Button>
<Button btnType={props.btnClass3}>{props.btnText3}</Button>
</td>
</tr>
)
}
</tbody>
</table>
);
};
export default companiesTable;
然后将该组件从包含两个选项卡的组件中装入两次。在一个标签中,我列出了活动帐户,在另一个标签中,列出了不活动帐户。
const companiesTabs = (props) => {
return (
<Tabs tabsClass={classes.TabList} tabContentClass={classes.TabContent}>
<div
label="Active"
tabClass={classes.TabItem}
activeClass={classes.TabItemActive}
hasLabel={true}
hasImg={false}
>
<CompaniesTable
isActive={true}
term={props.term}
companies={props.companies}
sortByName={props.sortByName}
sortByAddress={props.sortByAddress}
sortByAdded={props.sortByAdded}
sortingClass={props.sortingClass}
toggleSortingClass={props.toggleSortingClass}
btnClass1="secondary"
btnClass2="primary"
btnClass3="success"
btnText1="Delete"
btnText2="Deactivate"
btnText3="Sign in"
deleteInitiate={props.deleteInitiate}
/>
</div>
<div
label="Inactive"
tabClass={classes.TabItem}
activeClass={classes.TabItemActive}
hasLabel={true}
hasImg={false}
>
<CompaniesTable
isActive={false}
term={props.term}
companies={props.companies}
sortByName={props.sortByName}
sortByAddress={props.sortByAddress}
sortByAdded={props.sortByAdded}
sortingClass={props.sortingClass}
toggleSortingClass={props.toggleSortingClass}
btnClass1="secondary"
btnClass2="activate"
btnClass3="success"
btnText1="Delete"
btnText2="Activate"
btnText3="Sign in"
deleteInitiate={props.deleteInitiate}
/>
</div>
</Tabs>
);
};
export default companiesTabs;
然后我有一个包含选项卡组件的组件:
const companies = (props) => {
return (
<React.Fragment>
<CompaniesTabs
term={props.term}
companies={props.companies}
sortByName={props.sortByName}
sortByAddress={props.sortByAddress}
sortByAdded={props.sortByAdded}
sortingClass={props.sortingClass}
toggleSortingClass={props.toggleSortingClass}
deleteInitiate={props.deleteInitiate}
/>
</React.Fragment>
);
};
还有一个基于类的容器组件,其中包含状态和方法,并呈现Modal
,SearchBox
和Companies
组件。
export function searchingFor(term) {
return function(x) {
return x.name.toLowerCase().includes(term.toLowerCase()) || !term;
}
}
class CompaniesContainer extends Component {
constructor(props) {
super(props);
this.state = {
term: '',
sorting: false,
deleting: false,
deletingCompanyName: null,
companies: [
{
id: 1,
name: "Company 1",
street: "123 Some Street",
city: "London",
added: "03.04.19",
active: true,
},
{
id: 2,
name: "Company 2",
street: "321 Some other Street",
city: "New York",
added: "04.04.19",
active: false,
}
]
}
this.compareBy.bind(this);
this.sortBy.bind(this);
this.toggleSortingClass= this.toggleSortingClass.bind(this);
this.searchHandler = this.searchHandler.bind(this);
this.deleteInitiateHandler = this.deleteInitiateHandler.bind(this);
}
compareBy(key) {
return function (a, b) {
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
};
}
sortBy(key) {
let arrayCopy = [...this.state.companies];
arrayCopy.sort(this.compareBy(key));
this.setState({companies: arrayCopy});
}
toggleSortingClass() {
};
searchHandler(event){
this.setState({term: event.target.value});
}
deleteInitiateHandler = (name) => {
this.setState({deleting: true, deletingCompanyName: name});
}
deleteHandler = (companyIndex) => {
const companies = [...this.state.companies];
companies.splice(companyIndex, 1);
this.setState({companies: companies, deleting: false});
};
deleteCancelHandler = () => {
this.setState({deleting: false});
}
render() {
const {term, companies} = this.state;
return (
<React.Fragment>
<Modal
show={this.state.deleting}
modalClosed={this.deleteCancelHandler}
>
<DeleteCompany
delete={this.deleteHandler}
deleteCancel={this.deleteCancelHandler}
/>
</Modal>
<SearchBox
change={this.searchHandler}
value={term}
placeholder="Search Companies…"
/>
<Companies
term={term}
companies={companies}
sortByName={() => this.sortBy('name')}
sortByAddress={() => this.sortBy('city')}
sortByAdded={() => this.sortBy('id')}
sortingClass={this.state.sorting}
toggleSortingClass={this.toggleSortingClass}
deleteInitiate={this.deleteInitiateHandler}
/>
</React.Fragment>
);
}
};
export default CompaniesContainer;
最后,将一个DeleteCompany
组件安装到Modal
组件中,其中包含取消和删除按钮:
const deleteCompany = (props) => {
return (
<React.Fragment>
<h3 className={classes.ModalTitle}>Confirm deletion</h3>
<p className={classes.ModalText}>Are you sure you want to delete the company of <strong>{props.name}</strong></p>
<ul className={classes.ModalButtonsList}>
<li className={classes.ModalButtonsListItem}>
<Button btnType='primary' onClick={props.deleteCancel}>Cancel</Button>
</li>
<li className={classes.ModalButtonsListItem}>
<Button btnType='danger' onClick={props.delete}>Delete</Button>
</li>
</ul>
</React.Fragment>
);
};
我的问题是,当我单击特定公司行的删除按钮并通过单击模式内的删除按钮确认删除该行时,将删除错误的行。由于某种原因,无论我要删除哪一行,它总是删除表的第一行。有人可以帮我弄清楚为什么会这样吗?
答案 0 :(得分:2)
因为在DeleteCompany
组件中,您没有在delete
方法(在CompaniesContainer中定义为deleteHandler)中传递任何索引,
<Button btnType='danger' onClick={props.delete}>Delete</Button>
因此,您似乎正在执行类似[1,2,3].splice(undefined, 1)
的操作,它将始终删除第一个元素。
示例:
var a = [1,2,3,4];
a.splice(undefined, 1);
console.log('a', a);
解决方案是,单击删除按钮后,您正在将公司名称从CompaniesContainer
组件传递到companyTable
,因此请使用该名称删除公司而不是索引。
赞:
deleteHandler = (companyIndex) => {
this.setState(prevState => ({
companies: prevState.companies.filter(el => el.name != prevState.deletingCompanyName)
}))
};
注意:如果公司名称不是唯一的,请在此处传递任何唯一值而不是companiesTable
中的名称:
<Button btnType={props.btnClass1} onClick={() => props.deleteInitiate(item.id)}>{props.btnText1}</Button>
并使用该ID删除公司。