State和生命周期
为组件添加State和声明周期
状态与属性不同 state
是完全私有的,完全受控于当前组件
为组件添加state
方法
- 在class组件中添加构造方法,在构造方法的state属性中 初始化状态
this.state
- React元素展示的使用
state
属性的date值 class
组件中有提供声明周期方法
export default class Clock extends React.Component {
constructor(props) {
//需要将props属性来调用基础构造属性
super(props)
this.state = {
date : new Date()
}
}
tick() {
this.setState({
date: new Date()
})
}
componentDidMount() {
//this.timerID 用来存储一些我们需要的值
this.timerID = setInterval(() => {
this.tick()
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timerID)
}
render() {
return(
<h1>
Hello, 现在是时间 {this.state.date.toLocaleTimeString()}
</h1>
)
}
}
this.props
属性是React中内置属性this.state
是具有特殊含义的属性,这两个属性与展示有关,其他属性我们可以自行设置存储需要的值
State
更新状态必须使用setState({ key: value })
方法,而不能简单的直接赋值修改state对象,因为直接修改this.state
对象 虽然修改组件的内部状态,但是并没有驱动组件进行渲染,并不会反应state的的变化,而调用setState
方法,首先改变state值,然后驱动组件进行渲染,才能看到更新变化
this.setState({comment: 'Hello'});
状态更新机制:
React
为了提高性能,会将多个状态更新进行合并更新,因此你不能依靠确定现在的state
或者props
值就是你上次更新的state
和props
值,
如果想要依靠上次的状态或者属性进行更新,需要使用特殊的方法
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increment
};
});
组件的数据传递应该是自上向下传递,我们可以将状态作为属性传递给其组件,组件之间也只应该使用属性进行传递(状态是内部拥有的不能传递)
Props与state
- props用于定义外部接口,state用于记录内部状态
- props的赋值是在外部使用组件时,而state存在的目的就是让组件改变的
组件不应该修改传入的props值
生命周期
React的声明周期 经历以下三个过程:
- 装载过程: 组件第一次在DOM树中渲染的过程
- 更新过程: 组件被重新渲染的过程
- 卸载过程: 组件从DOM中删除的过程
装载过程
依次调用以下函数:
constractor
getInitialState
getDefaultProps
componetWillMount
reder
componentDidMount
constractor 为构造函数,通常用来
- 初始化state
- 绑定成员函数
getInitialState、getDefaultProps 是ES6之前使用React.creatClss
方法定义组件才会用到,我们现在使用ES6的class
在构造函数中初始化state,
ClassName.defaultProps
设置默认props
reder 函数是定义组件中最重要的方法,其他方法React.Component
都有默认实现,可以不用重写,这个方法必须实现,用来告诉react这个组件要渲染的DOM元素,我们不应该在这个方法中改变state;当然,如果组件想要什么都不渲染 我们可以返回null
或者false
componetWillMount、componentDidMount这两个函数发生在render函数的前后
我们通常不调用componetWillMount函数,因为此时并没有任何的渲染结果,即使调用setState
方法也不会引发任何的重绘,而在这个方法中的实现通常可以放到constractor()方法中
componentDidMount
在render函数调用完成后调用,但是并不会立即调用,而是在其它组件的render函数也完成后,将返回结果进行综合后,才能知道如何装载,完成装载,然后调用各个组件的componentDidMount函数。我们通常在此函数中进行ajax请求,然后填充组件内容
更新过程
依次调用一下函数:
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
componentWillReceiveProps(nextProps)
当父组件的render
函数被调用时,组件内的子组件或者组件的props改变或者都会经历更新过程,然后触发该函数。注意,当组件内的state改变时并不会触发该方法,因为该方法就是为了让我们根据新的props值来决定是否要更新state值,因为不是只有props改变时才调用该方法,我们需要比较该方法的nextProps与this.props比较,只有发生变化时才调用this.setState
当组件内调用
this.forceUpdate()
会强行引发一次重绘当父组件更新时,顺序是父组件先更新,完成后更新子组件
shouldComponentUpdate(nextProps, nextState)返回一个boolean
值,来决定此次渲染是否需要继续,如果返回false
,会立即停止更新过程,不进行后续更新.我们可以将nextProps
和nextState
与当前的this.props
和this.state
进行对比,来决定是否需要继续此次更新.注意,我们调用this.setState
引发更新,并不会立即更新state的值,在执行此函数时,仍是更新之前的值,因此不会影响我们进行判断
componentWillUpdate、componentDidUpdate
如果shouldComponentUpdate
函数返回true 就会调用这两个函数,分别在render
函数前后调用,与装载过程的Did函数不同,更新的Did函数不仅在浏览器端,在服务端也会执行,但是在服务器端的react代码,是不应该执行更新过程的。类似componentDidMount
函数,可以再componentDidUpdate
函数中执行第三方UI库的代码来更新UI,比如执行jquery
代码
卸载过程
componentWillUnmount卸载过程只会执行这一个函数,当组件将要从DOM树上移除时,适合做一些清理性的工作