Javascript 如何删除由其父级状态实例化的React组件类的实例?

Javascript 如何删除由其父级状态实例化的React组件类的实例?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,请原谅这个冗长的问题。我对React和ES6是全新的,我可能对这一点过于复杂了 我正在编写一个包含按钮组件的应用程序。此按钮调用onAddChild方法,该方法通过向存储在应用程序状态中的数组添加值来创建ColorModule类的另一个组件 在每个新创建的ColorModule中,我想包括另一个将删除该模块的按钮。由于该组件是由array.map方法创建的,因此我的想法是,如果我能找到与该组件对应的数组项的索引,并在array.splice中使用该索引,那么该组件可能会在未经测试的情况下被删除。

请原谅这个冗长的问题。我对React和ES6是全新的,我可能对这一点过于复杂了

我正在编写一个包含按钮组件的应用程序。此按钮调用onAddChild方法,该方法通过向存储在应用程序状态中的数组添加值来创建ColorModule类的另一个组件

在每个新创建的ColorModule中,我想包括另一个将删除该模块的按钮。由于该组件是由array.map方法创建的,因此我的想法是,如果我能找到与该组件对应的数组项的索引,并在array.splice中使用该索引,那么该组件可能会在未经测试的情况下被删除。也就是说,我不确定如何找到在onRemoveModule方法中使用该方法的索引

由两部分组成的问题:1我将如何在我的状态下找到数组项的索引,2如果我完全偏离了基准,或者有更好的方法来实现这一点,那么该解决方案是什么样的

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