0
点赞
收藏
分享

微信扫一扫

React中setState

React中setState_html

 

mountComponent 本质上是通过 递归渲染 内容的,由于递归的特性,父组件的 componentWillMount 一定在其子组件的 componentWillMount 之前调用,而父组件的 componentDidMount 肯定在其子组件的 componentDidMount 之后调用。

若使用 this.state.xxx 赋值更新状态,的确能够改变状态,但是无意义,也不会触发重新渲染。
因为,this.state 只是一个对象,单纯去修改一个对象的值无意义,去驱动 UI 的更新才是有意义的。
而 setState 方法被调用时,能驱动组件的更新过程,引发 shouldComponentUpdate、componentWillUpdate、 reader、 componentDidUpdate 等一系列方法调用,完成 UI 更新。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React中setState</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0

};
}
componentWillMount() {
let me = this;
me.setState({
count: me.state.count + 2
});
me.setState({
count: me.state.count + 1
});
}
componentDidMount() {
let me = this;
me.setState({
count: me.state.count + 2
});
me.setState({
count: me.state.count + 1
});
}

onClick() {
let me = this;
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});

setTimeout(() => {
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});
}, 1000);
}

render() {
console.log(this.state.count);
return (
<div>
<h1>{this.state.count}</h1>
<input type="button" value="点击我" onClick={this.onClick.bind(this)} /><br />
<br />
</div>
)
}
}

ReactDOM.render(
<App />,
document.getElementById('root')
);
</script>
</body>
</html>
  1. ​willmount​​​中的​​setState​​​会合并成一次执行,​​count​​​只会保留最后一次的设置,前面的放弃,所以​​willmount​​​之后是​​1​​​,并不是​​3​​​;并且在​​render​​​之前执行,不会引起新的​​render​
  2. render之后执行didMount,setState做同样的处理,这是​​count​​​是​​2​​,并且引起新的render
  3. 点击按钮,​​setState​​​做同样处理,​​count​​​是​​3​​​,引起新的​​render​

​备注:​

定时器中的​​setState​​​没走​​react​​​的事物机制,执行时批量更新没被设置​​true​​,所以每次都直接render了。

在按钮原生事件中定义的​​setState​​,和定时器效果一样,每次​​setState​​都会引起新的​​render​

 

 

因为setState并不会立刻修改this.state的值,所以下面的code可能产生很不直观的结果。

function incrementMultiple() {
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
}

直观上来看,当上面的incrementMultiple函数被调用时,组件状态的count值被增加了3次,每次增加1,那最后count被增加了3,但是,实际上的结果只给state增加了1。

原因并不复杂,就是因为调用this.setState时,并没有立即更改this.state,所以this.setState只是在反复设置同一个值而已,上面的code等同下面这样。

function incrementMultiple() {
const currentCount = this.state.count;
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
}

currentCount就是一个快照结果,重复地给count设置同一个值,不要说重复3次,哪怕重复一万次,得到的结果也只是增加1而已。

 

 

 

 

 

 

 


举报

相关推荐

0 条评论