为什么componentDidUpdate看不到新插入的dom节点?

时间:2016-11-30 14:02:24

标签: javascript reactjs

我有这个案例,也许我错过了反应componentDidMount如何工作的东西,或者这可能是一个奇怪的行为(正确知道我不能提供一个真正的小提琴插件,但我我很确定问题比插件本身更广泛。)

var Hello = React.createClass({
  getInitialState() {
    return {content: '<div id="target">ciao!</div>'}
  },

  componentDidMount() {
    const target = $('#target').init();
    this.target = target;
  },

  componentWillReceiveProps(nextProps) {
    if (condition) {
        this.target.destroy(); // this remove even the DOM node
    }
  },

  componentDidUpdate() {
    const target = $('#target').init(); // HERE PROBLEM! can't find the #target element
    this.target = target;
  }

  render: function() {
    return <div>Hello {this.state.content}</div>;
  }
});

我无法理解为什么在'condition'为真并且dom节点被插件破坏之后,componentDidUpdate找不到我认为应该是#target的{​​{1}}在componentWillReceiveProps之后的第一个渲染中重新渲染。我希望能够在那里,因为它从最初状态读取它永远不会改变。

我错过了什么?

2 个答案:

答案 0 :(得分:1)

由于您正在使用jQuery操作react元素(this.state.content),这使得React无法检测到呈现内容的更改。所以当你第一次渲染时

  1. componentDidUpdate具有初始状态和完全呈现的组件,包括#target
  2. 在调用$('#target').init()之后,渲染的组件在外部更改,而不通知React
  3. 调用$('#target').destroy()
  4. ,从DOM中删除#target节点,而不通知React
  5. 因此,当您componentDidUpdate拨打$('#target').init()时,您无法找到#target,因为React未检测到#target中的任何更改,并且由于React进行选择性重新渲染,#target不会重新生成。
  6. 因此,您可以做的一件事是更新componentWillReceiveProps(in condition check)中的状态,请注意data-updated字段,这将确保React检测到{{1}的状态更改},因此将重新渲染组件,您将在this.state.content

    中再次找到#target
    componentDidUpdate

    鉴于此,我建议您在React中查看refs

答案 1 :(得分:0)

在React中,您永远不应该在this.setState()生命周期方法中执行componentDidMount(),因为它会导致布局颠簸。 在此处查看有关布局化的更多信息:https://blog.idrsolutions.com/2014/08/beware-javascript-layout-thrashing/

原因是this.setState()导致重新渲染(调用render()两次)。这在componentDidMount()中发生一次,在实际渲染方法中发生一次。您应该找到一种方法从setState()中移除componentDidMount,您的问题可能会得到解决。作为初步尝试,我会在this.setState()方法

中移动componentWillMount()