挂载阶段的组件生命周期

ReactDOM.render(
 <Header />, 
  document.getElementById('root')
)
//*********会编译成
ReactDOM.render(
  React.createElement(Header, null), 
  document.getElementById('root')
)

//*********他会做
// React.createElement 中实例化一个 Header
const header = new Header(props, children)
// React.createElement 中调用 header.render 方法渲染组件的内容
const headerJsxObject = header.render()

// ReactDOM 用渲染后的 JavaScript 对象来来构建真正的 DOM 元素
const headerDOM = createDOMFromObject(headerJsxObject)
// ReactDOM 把 DOM 元素塞到页面上
document.getElementById('root').appendChild(headerDOM)

可以理解为,组件调用过程为:

-> constructor()
-> componentWillMount()
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()
 

我们把react.js将组件渲染,并且构造DOM元素然后塞入页面的过程称为组件的挂载。在其内部,每个组件都会经历一个过程:

初始化组件 --> 挂载组件。

挂载阶段组件的生命周期

一般来说,组件自身的状态的初始化工作会在constructor里面去做。

一些组件的启动的动作,如ajax数据的拉取操作,定时器的启动等就可以在componentWillMount里面

组件从页面上销毁时,需要清理一些数据,就会放在componentWillUnmount里面

更新阶段组件的生命周期

  • shouldComponentUpdate(nextProps, nextState):你可以通过这个方法控制组件是否重新渲染。如果返回 false 组件就不会重新渲染。这个生命周期在 React.js 性能优化上非常有用。
  • componentWillReceiveProps(nextProps):组件从父组件接收到新的 props 之前调用。
  • componentWillUpdate():组件开始重新渲染之前调用。
  • componentDidUpdate():组件重新渲染并且把更改变更到真实的 DOM 以后调用。
在React.js当中,你基本不需要和DOM直接打交道。它提供了一系列的on*方法帮助我们进行事件监听。所以react.js中不需要直接调用addEventListener的DOM API。
但是react.js并不能完全满足我们所有DOM操作需求。react.js当中提供了ref属性来帮助我们获取已经挂载的元素的DOM节点。可以给某个JSX元素加上ref属性。
class AutoFocusInput extends Component {
  componentDidMount () {
    this.input.focus()
  }

  render () {
    return (
      <input ref={(input) => this.input = input} />
    )
  }
}

ReactDOM.render(
  <AutoFocusInput />,
  document.getElementById('root')
)

但是原则是:能不用就不用,特别要避免用ref做react.js本身就可以帮助你做到的页面自动跟新的操作和时间监听。

 

dangerouslySetHTML 和 style 属性

在react.js中所有表达式插入的内容都会被自动转义,任何的html格式都会被转义掉

如:this.state = { content: '<h1>React.js 小书</h1>'},不会以动态html格式显示,而是直接将内容显示成字符串文本。

它提供了一个属性 dangerouslySetInnerHTML,可以让我们设置动态设置元素的 innerHTML     dangerouslySetInnerHTML={{__html: this.state.content}}

React.js 中的元素的 style 属性的用法和 DOM 里面的 style 不大一样,普通的 HTML 中的:

//React.js 中的元素的 style 属性的用法和 DOM 里面的 style 不大一样,普通的 HTML 中的:

<h1 style='font-size: 12px; color: red;'>React.js 小书</h1>

//在 React.js 中你需要把 CSS 属性变成一个对象再传给元素:
<h1 style={{fontSize: '12px', color: 'red'}}>React.js 小书</h1>

style接受一个对象,这个元素里面是这个元素的css属性键值对,原来属性中带-都去掉-换成驼峰命名。

 

PropTypes 和组件参数验证

JavaScript是一门灵活的语言。它的灵活性体现在弱类型,高阶函数等语言特性上。变量没有固定类型可以随意赋值,但也很容易出现bug。

react.js提供了一种给配置参数加上类型验证。

 1 import React, { Component, PropTypes } from 'react'
 2 
 3 class Comment extends Component {
 4   static propTypes = {
 5     comment: PropTypes.object.isRequired //可以通过 isRequired 关键字来强制组件某个参数必须传入
 6   }
 7 
 8   render () {
 9     const { comment } = this.props
10     return (
11       <div className='comment'>
12         <div className='comment-user'>
13           <span>{comment.username} </span>14         </div>
15         <p>{comment.content}</p>
16       </div>
17     )
18   }
19 }
//React.js 提供的 PropTypes 提供了一些列的数据类型可以用来配置组件的参数:
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
...
编码习惯参考
组件的私有方法都有用 _开头,所有时间监听的方法都用handle开头,把事件监听方法传给组件的时候,属性名用on开头。
 1 class CommentInput extends Component {
 2   constructor () {
 3     super()
 4     this.state = {
 5       username: '',
 6       content: ''
 7     }
 8   }
 9 
10   componentDidMount () {
11     this.textarea.focus()
12   }
13 
14   _saveUsername (username) {
15     localStorage.setItem('username', username)
16   }
17 
18   handleUsernameBlur (event) {
19     this._saveUsername(event.target.value)
20   }
21 ...
<CommentInput onSubmit={this.handleSubmitComment.bind(this)} />

另外,组件的内容编写顺序:

1.static开头的类属性,如defaultProps,propTypes;

2.构造函数,constructor;

3.getter、setter;

4.组件生命周期;

5.私有方法,以_开头;

6.事件监听方法,handle*;

7.render*开头的方法,有时候render()方法里面的内容会分开到不同的函数里面进行,这些方法都已render开头;

8.render();

 
posted on 2020-04-17 17:27  gqqi  阅读(166)  评论(0编辑  收藏  举报