Javascript 如何删除由其父级状态实例化的React组件类的实例?
请原谅这个冗长的问题。我对React和ES6是全新的,我可能对这一点过于复杂了 我正在编写一个包含按钮组件的应用程序。此按钮调用onAddChild方法,该方法通过向存储在应用程序状态中的数组添加值来创建ColorModule类的另一个组件 在每个新创建的ColorModule中,我想包括另一个将删除该模块的按钮。由于该组件是由array.map方法创建的,因此我的想法是,如果我能找到与该组件对应的数组项的索引,并在array.splice中使用该索引,那么该组件可能会在未经测试的情况下被删除。也就是说,我不确定如何找到在onRemoveModule方法中使用该方法的索引 由两部分组成的问题:1我将如何在我的状态下找到数组项的索引,2如果我完全偏离了基准,或者有更好的方法来实现这一点,那么该解决方案是什么样的Javascript 如何删除由其父级状态实例化的React组件类的实例?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,请原谅这个冗长的问题。我对React和ES6是全新的,我可能对这一点过于复杂了 我正在编写一个包含按钮组件的应用程序。此按钮调用onAddChild方法,该方法通过向存储在应用程序状态中的数组添加值来创建ColorModule类的另一个组件 在每个新创建的ColorModule中,我想包括另一个将删除该模块的按钮。由于该组件是由array.map方法创建的,因此我的想法是,如果我能找到与该组件对应的数组项的索引,并在array.splice中使用该索引,那么该组件可能会在未经测试的情况下被删除。
imports...
class App extends Component {
static propTypes = {
children: PropTypes.node,
};
constructor(props) {
super(props);
this.state = {
// Here's the array in question...
moduleList: [1],
};
this.onAddChild = this.onAddChild.bind(this);
this.onRemoveModule = this.onRemoveModule.bind(this);
this.className = bemClassName.bind(null, this.constructor.name);
}
onAddChild(module) {
const moduleList = this.state.moduleList;
this.setState({ moduleList: moduleList.concat(1) });
}
onRemoveModule( e ) {
e.preventDefault();
...¯\_(ツ)_/¯
}
render() {
const { className } = this;
return (
<div className={className('container')}>
<Header onAddChild={this.onAddChild} /> /* Add module button lives here */
<div className="cf">
{this.state.moduleList.map(
( delta, index ) => {
return (
<ColorModule
className="cf"
onRemove={this.onRemoveModule}
key={index}
moduleId={'colorModule' + index}
/>
); /* Remove module button would live in the module itself */
}
)}
</div>
</div>
);
}
}
export default App;
这一部分非常简单,您只需将索引作为道具传递给ColorModule组件,当在其中调用onRemove方法时,您可以将其传递回onRemoveModule。然而,react是基于键进行优化的,给每个模块实例一个唯一的id是一个非常好的主意
class App extends Component {
static propTypes = {
children: PropTypes.node,
};
constructor(props) {
super(props);
this.state = {
// Here's the array in question...
moduleList: [1],
};
this.onAddChild = this.onAddChild.bind(this);
this.onRemoveModule = this.onRemoveModule.bind(this);
this.className = bemClassName.bind(null, this.constructor.name);
}
onAddChild(module) {
const moduleList = this.state.moduleList;
this.setState({ moduleList: moduleList.concat(uuid()) }); //uuid must return a unique id everytime to be used as component key
}
onRemoveModule( index ) {
// now with this index you can update the moduleList
}
render() {
const { className } = this;
return (
<div className="cf">
{this.state.moduleList.map(
( delta, index ) => {
return (
<ColorModule
className="cf"
index={index}
onRemove={this.onRemoveModule}
key={delta}
moduleId={'colorModule' + delta}
/>
);
}
)}
</div>
);
}
}
查看此答案以了解有关的更多详细信息。我最终使用了@shubhamkhattri提供的一些指导来解决此问题。我不知道如何生成唯一ID!,但我采取了一种稍微不同的方法,在应用程序中使用状态操纵来处理解决方案,而不需要在我的ColorModule组件中使用新方法。我也不知道在ES6中使用curry,因此发现使得传递操作我的状态数组所需的索引值成为可能 如果我在这里偏离了底线或效率低下,我肯定会以更好的方式接受反馈
class App extends Component {
constructor(props) {
super(props);
this.state = {
moduleList: [{ id: UniqId(), removeModule: false }],
};
this.onAddChild = this.onAddChild.bind(this);
this.className = bemClassName.bind(null, this.constructor.name);
}
onAddChild(module) {
const moduleList = this.state.moduleList;
this.setState({
moduleList: moduleList.concat({
id: UniqId(),
removeModule: false,
}),
});
}
onRemoveModule = ( i, arr ) => (e) => {
const moduleList = this.state.moduleList;
e.preventDefault();
moduleList[i].removeModule = true;
this.setState({ moduleList: moduleList });
}
render() {
const { className } = this;
return (
<div className={className('container')}>
<Header onAddChild={this.onAddChild} />
<div className="cf">
{this.state.moduleList.map(
( delta, index ) => {
if ( !this.state.moduleList[index].removeModule ) {
return (
<ColorModule
className="cf"
onRemove={this.onRemoveModule( index, this.state.moduleList )}
index={index}
key={delta.id}
moduleId={'colorModule' + delta}
/>
);
}
}
)}
</div>
</div>
);
}
}
我建议不要将1存储在moduleList数组的状态中,而是放置一个唯一的id来标识元素,并将该id用作键,并将其传递给子组件,使用该id删除该组件。@MayankShukla很好的建议-完成,谢谢!
class App extends Component {
constructor(props) {
super(props);
this.state = {
moduleList: [{ id: UniqId(), removeModule: false }],
};
this.onAddChild = this.onAddChild.bind(this);
this.className = bemClassName.bind(null, this.constructor.name);
}
onAddChild(module) {
const moduleList = this.state.moduleList;
this.setState({
moduleList: moduleList.concat({
id: UniqId(),
removeModule: false,
}),
});
}
onRemoveModule = ( i, arr ) => (e) => {
const moduleList = this.state.moduleList;
e.preventDefault();
moduleList[i].removeModule = true;
this.setState({ moduleList: moduleList });
}
render() {
const { className } = this;
return (
<div className={className('container')}>
<Header onAddChild={this.onAddChild} />
<div className="cf">
{this.state.moduleList.map(
( delta, index ) => {
if ( !this.state.moduleList[index].removeModule ) {
return (
<ColorModule
className="cf"
onRemove={this.onRemoveModule( index, this.state.moduleList )}
index={index}
key={delta.id}
moduleId={'colorModule' + delta}
/>
);
}
}
)}
</div>
</div>
);
}
}