如何从特定单击的响应中删除数组中的索引
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从特定单击的响应中删除数组中的索引相关的知识,希望对你有一定的参考价值。
我正在构建一个测验/调查构建器,一种CMS界面,允许用户通过单击他们想要的问题类型来添加任意数量的问题。
首先,我的状态在App组件中设置如下:
state = {
components: API.components,
comps: []
}
管理屏幕具有选定数量的按钮,这些按钮将激活问题onClick。问题来自API.components。例如,我们有: - 欢迎辞 - 谢谢你的消息 - 是或否
/* 1. Generate a list of buttons with onClick props.addQuestion passing a fixed id via 'i' parameter */
const QuestionTypes = props => {
return (
<div data-name='typequestion'>
{props.details.map((el, i) => <div key={i}><button className="sm" onClick={() => props.addQuestion(i)}>{el.label}</button></div>)}
</div>
)
}
请参阅菜单问题截图:https://www.awesomescreenshot.com/image/3982311/8964261115690780c3f67d390ce08665
onClick,这些按钮中的每一个都将触发'addQuestion'方法,该方法将固定ID(键)传递给'selectComponent'函数,以将所选组件添加到comps []数组:
/* onClick, a method 'addQuestion' is called */
/* This method will setState and call a function selectComponent passing a key (id) in order to select the correct component */
addQuestion = key => {
this.setState({
comps: [...this.state.comps, this.selectComponent(key)]
});
}
selectComponent函数有一个开关来传递正确的组件:
selectComponent = (key) => {
switch(key) {
case 0:
return <WelcomeMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
case 1:
return <ThankYouMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
case 2:
return <YesNo details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
default:
return 'Please select a component from the left side menu'
}
}
这将为comps []数组添加一个元素:
[
0: {element here ..}
1: {element here ..} etc.
]
这是组件代码的示例:
const ThankYouMessage = props => (
<section className="ui-component-view" data-name="thankyou">
<img src={ThankYouImage} alt="x" />
<h3>Thanks for completing our form!</h3>
<div>
<DeleteButton deleteQuestion={props.deleteQuestion} />
</div>
</section>
);
请参阅选定的欢迎消息组件截图:https://www.awesomescreenshot.com/image/3982315/f59e1bf79a31194aa3ee3ad2467658a0
问题:
如您所见,每个组件都有一个删除按钮。虽然每个组件都没有问题地添加到阵列中,但是当我单击删除按钮时,我找不到仅删除所选组件的方法。
我曾尝试使用.filter(),splice()但我没有为新创建或更新的数组列表提供正确的索引。我想用React的方式来做,而不是jQuery或javascript-ish。
删除按钮的示例。请注意,props.index传递的是原始单击的按钮id(key),它与新的comps []数组索引不匹配:
const DeleteButton = props => (
<span className="deleteButton" onClick={() => props.deleteQuestion(props.index)}>×<small>Delete</small></span>
);
export default DeleteButton;
这里是删除方法:
deleteQuestion = e => {
const comps = [...this.state.comps]
// 2. here I need to add something that will DELETE ONLY the clicked button index for that component
// 3. Update state
this.setState({ comps });
}
请参阅App组件的完整代码:class App extends React.Component {
state = {
components: API.components,
comps: [],
multichoice: {}
}
selectComponent = (key) => {
switch(key) {
case 0:
return <WelcomeMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
case 1:
return <ThankYouMessage details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
case 2:
return <YesNo details={this.state.components[key]} deleteQuestion={this.deleteQuestion} comps={this.state.comps} index={fuck} />
break;
default:
return 'Please select a component from the left side menu'
}
}
addQuestion = key => {
this.setState({
comps: [...this.state.comps, this.selectComponent(key)]
});
}
deleteQuestion = e => {
const comps = [...this.state.comps]
// 2. here I need to add something that will DELETE ONLY the component related to the delete button
// 3. Update state
this.setState({ comps });
}
render() {
return (
<Container>
<Row>
<Col>
<h1>Survey Builder </h1>
</Col>
</Row>
<Row>
<Col lg={3} className="border-right">
<QuestionTypes addQuestion={this.addQuestion} details={this.state.components} />
</Col>
<Col lg={9}>
<Row>
<Col lg={12}>
<QuestionEdit comps={this.state.comps} details={this.state.components} />
</Col>
</Row>
</Col>
</Row>
</Container>
)
}
}
export default App;
您不应该将组件保持在状态内(因为这会破坏组件的生命周期并且很难比较它们)。相反,只需保留键:
addQuestion = key => {
this.setState({
comps: [...this.state.comps, key]
});
}
然后在render()
中,将键映射到组件:
{this.state.comps.map((key, index) => <SomeComponent remove={() => this.removeQuestion(index)} />)}
现在removeQuestion
可以简单地:
removeQuestion(index) {
this.setState(({ comps }) => ({ comps: comps.filter((_, i) => i !== index) }));
}
编辑:不应该在州上持有任何组件,只是代表问题的对象。
comps
状态应该是不可变的,这意味着每次添加或删除问题时,您应该从旧的数组中创建一个新的数组,当前处于状态。
由于您没有使用任何高级状态管理器(如Redux等),此时也不应该使用,我建议在每个问题上都有一个数据属性,上面有问题ID。点击后,您可以从点击事件所携带的目标中获取问题ID,并使用它来确定问题项目在comps
状态中的位置。有了它,创建一个新的comps
状态,通过构造一个没有你刚刚删除的问题的新数组。
我还建议不要在这里使用开关/盒子,因为它无视open/close principle。我想你会找到一种字典方法,你可以将问题的类型映射到相应的组件,更加可扩展和可维护。
希望这可以帮助 :)
以上是关于如何从特定单击的响应中删除数组中的索引的主要内容,如果未能解决你的问题,请参考以下文章