首页 文章

ReactJS - 销毁旧的Component-Instance并创建新的

提问于
浏览
0

我有一个可能令人困惑的问题,因为它不符合标准行为如何反应和虚拟dom工作,但我想知道答案无论如何 .

想象一下,我有一个简单的反应组件,称为“容器” . Container-component在render-method中有一个“div”,它包含另一个名为“ChildContainer”的组件 . 围绕“ChildContainer”的“div”具有id“wrappingDiv” .

例:

render() {
  <Container>
    <div id="wrappingDiv">
      <ChildContainer/>
    </div>
  </Container
}

如何销毁“ChildContainer”组件实例并创建一个完全新的实例 . 这意味着调用旧实例的“ComponentWillUnmount”,并调用新组件的“ComponentDidMount” .

我不希望通过更改状态或道具来更新旧组件 .

我需要这种行为,因为我们的合作伙伴公司的外部库有一个更改dom项的库,而在React中,当我更新组件时,我会得到一个“Node not found”异常 .

1 回答

  • 4

    如果为组件提供 key ,并在重新呈现时更改 key ,则旧组件实例将卸载,新组件实例将挂载:

    render() {
      ++this.childKey;
      return <Container>
        <div id="wrappingDiv">
          <ChildContainer key={this.childKey}/>
        </div>
      </Container>;
    }
    

    孩子每次都会有一个新的 key ,所以React会认为它是一个列表的一部分并扔掉旧的,创建一个新列表 . 组件中导致重新呈现的任何状态更改都将强制对子项执行卸载和重新创建的行为 .

    实例:

    class Container extends React.Component {
      render() {
        return <div>{this.props.children}</div>;
      }
    }
    
    class ChildContainer extends React.Component {
      render() {
        return <div>The child container</div>;
      }
      componentDidMount() {
        console.log("componentDidMount");
      }
      componentWillUnmount() {
        console.log("componentWillUnmount");
      }
    }
    
    class Example extends React.Component {
      constructor(...args) {
        super(...args);
        this.childKey = 0;
        this.state = {
          something: true
        };
      }
    
      componentDidMount() {
        let timer = setInterval(() => {
          this.setState(({something}) => ({something: !something}));
        }, 1000);
        setTimeout(() => {
          clearInterval(timer);
          timer = 0;
        }, 10000);
      }
      
      render() {
        ++this.childKey;
        return <Container>
          {this.state.something}
          <div id="wrappingDiv">
            <ChildContainer key={this.childKey}/>
          </div>
        </Container>;
      }
    }
    
    ReactDOM.render(
      <Example />,
      document.getElementById("root")
    );
    
    <div id="root"></div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
    

    话虽如此,对插件的潜在问题可能有更好的答案 . 但上面解决了实际问的问题...... :-)

相关问题