【问题标题】:Unmounting React.js node卸载 React.js 节点
【发布时间】:2014-02-09 17:07:16
【问题描述】:

我正在尝试使用 this._rootNodeID 卸载 React.js 节点

 handleClick: function() {

        React.unmountComponentAtNode(this._rootNodeID)

 }

但它返回false

handleClick 在我点击一个元素时被触发,并且应该卸载根节点。关于unmountComponentAtNodehere的文档

我也试过这个:

React.unmountComponentAtNode($('*[data-reactid="'+this._rootNodeID+'"]')[0])

该选择器适用于 jQuery.hide(),但不适用于卸载它,而文档指出它应该是 DOMElement,就像您将用于 React.renderComponent 一样

经过几次测试,结果证明它适用于一些元素/选择器。

它以某种方式与选择器一起工作:document.getElementById('maindiv'),其中maindiv 是一个不是用 React.js 生成的元素,只是普通的 html。然后它返回true

但是,一旦我尝试选择使用 React.js 生成的不同 ElementById,它就会返回 false。它也不适用于document.body,尽管如果我对它们进行控制台记录,它们基本上都会返回相同的东西(getElementsByClassName('bla')[0] 也不起作用)

应该有一种简单的方法可以通过this 选择节点,而不必求助于 jQuery 或其他选择器,我知道它就在某个地方..

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

从您安装它们的同一个 DOM 元素中卸载组件。因此,如果您执行以下操作:

ReactDOM.render(<SampleComponent />, document.getElementById('container'));

然后你会卸载它:

ReactDOM.unmountComponentAtNode(document.getElementById('container'));

这里是a simple JSFiddle,我们在这里挂载组件,然后在 3 秒后卸载它。

【讨论】:

  • @TrySpace 如果您想从组件本身触发卸载,您可以将 DOM 元素作为道具传入并在需要时引用它:http://jsfiddle.net/iamlacroix/JRy7W/2
  • @TrySpace 在上面的 JSFiddle 中,它不起作用,因为您试图在渲染的组件 #element 上调用 unmount 而不是您用来挂载它的容器 #container。 React 不会替换容器本​​身,只是替换它的innerHTML。这样您就可以随时再次引用该容器(例如,使用新道具重新安装,替换为不同的组件等)
  • @MichaelLaCroix 如果您在容器中有组件列表并且只想删除一个怎么办?由于只有一个容器,因此在该容器上调用 React.unmountComponentAtNode 将删除所有组件。你是怎么解决的?
  • @Marconi 顶级 React 组件只能有一个根节点,因此您可能希望使用基于该组件的 props 或状态的逻辑来确定是否应包含子组件.
  • @MichaelLaCroix 嘿,谢谢,但我昨晚通过为每个子组件添加单独的容器来管理,然后删除变得更容易,因为它有自己的容器。
【解决方案2】:

这对我有用。如果 findDOMNode 返回 null,您可能需要采取额外的预防措施。

ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(this).parentNode);

【讨论】:

  • 如果 Component.render 返回 null(在这种情况下 Component.getDOMNode() 也返回 null),此代码将引发异常。
  • 这段代码非常适合我。添加 parentNode 可以帮助我删除整个 React 组件。
【解决方案3】:

我使用的例子:

unmount: function() {
  var node = this.getDOMNode();
  React.unmountComponentAtNode(node);
  $(node).remove();
},

handleClick: function() {
  this.unmount();
}

【讨论】:

  • $(node) 是否使用 jQuery?
【解决方案4】:

你不需要卸载组件,简单的解决方案是改变状态并呈现一个空的 div

const AlertMessages = React.createClass({
  getInitialState() {
    return {
      alertVisible: true
    };
  },
  handleAlertDismiss() {
    this.setState({alertVisible: false});
  },
  render() {
    if (this.state.alertVisible) {
      return (
        <Alert bsStyle="danger" onDismiss={this.handleAlertDismiss}>
          <h4>Oh snap! You got an error!</h4>
        </Alert>
      );
    }
    return <div></div>
  }
});

【讨论】:

  • 渲染一个空的 div 拯救了我的一天。感谢您的提示。
【解决方案5】:

正如the GitHub issue you filed中提到的,如果你想访问组件的DOM节点,你可以使用this.getDOMNode()。但是,组件不能自行卸载。请参阅 Michael 的回答,了解正确的做法。

【讨论】:

  • a component can not unmount itself 可能是这样
  • 在 react 0.14.x 中,this.getDOMNode 已被弃用。请使用 ReactDOM.findDOMNode(this.refs.[nodeName]) 自定义组件或 this.refs[nodeName] 支持 JSX 标签。
【解决方案6】:

首先,我也是 reactjs 新手。当然我们可以通过切换 state 来控制组件,但是当我尝试和测试时,我明白了,React.unmountComponentAtNode(parentNode) 只能卸载由React.render(&lt;SubComponent&gt;,parentNode) 呈现的组件。所以要删除的&lt;SubComponent&gt;必须通过React.render()方法追加,所以我写了代码

<script type="text/jsx">

    var SubComponent = React.createClass({
        render:function(){
            return (
                    <div><h1>SubComponent to be unmouned</h1></div>
            );
        },
        componentWillMount:function(){
            console.log("componentWillMount");
        },
        componentDidMount:function(){
            console.log("componentDidMount");
        },
        componentWillUnmount:function(){
            console.log("componentWillUnmount");
        }

    });

    var App = React.createClass({

        unmountSubComponent:function(){
            var node = React.findDOMNode(this.subCom);
            var container = node.parentNode;
            React.unmountComponentAtNode(container);
            container.parentNode.removeChild(container)
        },

        componentDidMount:function(){
            var el = React.findDOMNode(this)
            var container = el.querySelector('.container');
            this.subCom = React.render(<SubComponent/> ,  container);
        },

        render:function(){

            return (
                <div className="app">
                    <div className="container"></div>
                    <button onClick={this.unmountSubComponent}>Unmount</button>
                </div>
            )
        }
    });

    React.render(<App/> , document.body);
</script>

运行jsFiddle中的示例代码,试一试。

注意:示例代码中React.findDOMNode替换为getDOMNode作为reactjs版本问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-30
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2018-07-03
    • 2014-04-19
    • 1970-01-01
    相关资源
    最近更新 更多