ComponentDidMount和ComponentWillMount有什么区别?

3

我有一个问题,关于componentDidMount 何时触发,我刚开始接触React,并且文档中的例子很模糊。为什么我的组件没有被触发?

var App = React.createClass({    
     getInitialState: function() {   
      var events = ['initial state has been called'];  
      return {   
       events: events   
      }    
     },         
     componentWillMount: function() {    
      return {    
       mount: this.state.events.push('componentWillMount has been called')    
      }    
     },    
     componentDidMount: function() {    
      return     
      console.log('mounted!');      
     },    
     render: function() {    
      var eventMap = this.state.events.map(function(event, i) {   
     return <li key={i}>{event}</li>;       
    })
      return (    
       <div>
        <ul>
         {eventMap}
        </ul>
       </div>
      )
     }
    })

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

"为什么我的组件没有触发?" --- 这句话的确切意思是什么? - zerkms
当这段代码运行时,输出是一个ul。在Ul中是'initialState已被调用','componentWillMount已被调用',但它不会console.log('mounted!')。我很好奇为什么。 - visylvius
它不会输出“mounted!”,因为你的console.log语句在return之后。所以componentDidMount函数在console.log之前返回。 - zerkms
我很困惑为什么componentDidMount没有运行。 - visylvius
啊..那是个公正的观点。但即使没有控制台日志,当我返回一个与componentWillMount相似的键值对对象时,它也不会将其添加到数组中。 - visylvius
那是因为componentWillMount不应该返回任何东西(并且在文档中明确说明了)。 - zerkms
1个回答

3
你可能会问为什么你的eventMap不包含字符串'componentWillMount has been called'li。这是因为你不能将项目pushthis.state中。你必须调用this.setState,这将导致你的render函数再次运行。
此外,不清楚为什么你返回一个带有键mount的对象,因为componentWillMount不会将其结果传递给任何东西。
componentWillMount: function() {    
  var events = this.state.events;
  events.push('a new value')    
  this.setState({ events: events }); // important!
}   

你可能也在想为什么在你的componentDidMount函数中控制台消息没有出现。这是因为在return之后不能有换行:

componentDidMount: function() {    
  return // magic semi-colon gets added here, nothing below will happen.
  console.log('mounted!');      
}   

正确的做法是将你要返回的东西放在同一行上(或使用括号)

componentDidMount: function() {    
  return console.log('mounted!');
},

或者

componentDidMount: function() {    
  return (    
    console.log('mounted!');      
  )
}

但是,就像有些无礼的@zerkms指出的那样,从这个函数中返回任何东西都没有意义...这只是说明为什么你的console.log没有触发。

我认为这些关于组件生命周期的文档非常清晰明了,所以请保持打开:

https://facebook.github.io/react/docs/component-specs.html


1
你对 componentDidMount 的建议很奇怪:return console.log('mounted!'); 语句完全没有意义。 - zerkms
这不是一个建议,而是对 OP 代码的纠正,因为他想知道为什么控制台日志没有触发。 - azium
2
它回答了OP的问题,如果你有更好的答案,请发表。 - azium
1
说某人的代码很愚蠢并不是粗鲁,而是诚实。在一些不好的东西上说“干得好”是最具破坏性的。 - zerkms
2
说别人的代码很愚蠢是不礼貌的。大多数人在学习过程中都会犯错误。你可以说这段代码不正确,并展示更好的实现方式。这样做可以让你成为一个更好的专业人士,人们会听取你的意见,从而真正产生影响。 - tiomno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接