如果你接触过 React 开发,肯定会遇到 setState() 方法,它是在类组件中更新 state 的方式,也是更新 UI 的主要方法。
方法格式如下:
setState(updater, [callback])
根据 React 官方文档,不保证在调用此方法后 state 会立即更新:
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
我们可以用一些例子探索不同场景下的表现。
例子 1. 在 componentDidMount 生命周期函数里使用 setState()
class App extends React.Component { constructor(props) { super(props); this.state = { count: 1 }; } componentDidMount() { this.setState({ count: 2 }) console.log('count:', this.state.count); // count: 1 } render() { return ( <div className="App"> Count: {this.state.count} </div> ) } }
在控制台看到 this.state.count 输出值为 1,并非刚设置的 2。所以在此情况下对 state 的更新是延迟执行的。
例子 2. 在合成事件监听器里使用 setState()
class App extends React.Component { constructor(props) { super(props); this.state = { count: 1 }; } hanldeClick = () => { console.log('before click, count:', this.state.count); // before click, count: 1 this.setState({ count: 3 }); console.log('after click, count:', this.state.count); // after click, count: 1 } render() { return ( <div className="App"> Count: {this.state.count} <p><button onClick={this.hanldeClick}>click</button></p> </div> ) } }
handleClick 是一个监听点击事件的函数,在函数内部添日志发现在调用 setState() 前后直接访问 this.state.count 输出值并没有变化,都是原来的值 1。
所以此情况下对于 state 更新也是延迟执行的。
例子3. 在原生事件监听器中
class App extends React.Component { constructor(props) { super(props); this.state = { count: 1 }; this.btn = React.createRef(); } hanldeClick = () => { console.log('before click, count:', this.state.count); // before click, count: 1 this.setState({ count: 3 }); console.log('after click, count:', this.state.count); // after click, count: 3 } componentDidMount() { this.btn.current.addEventListener('click', this.hanldeClick); } render() { return ( <div className="App"> Count: {this.state.count} <p><button ref={this.btn}>click</button></p> </div> ) } }
上述代码中用了 addEventListener() 浏览器原生事件 API 为按钮注册了事件监听器,并在其中先打印出之前的 state,然后调用 setState() 并再次打印 state 值。点击按钮,输出显示在调用 setState() 后 state 值立即更新了。
例子4. 在 setTimeout 中
class App extends React.Component { constructor(props) { super(props); this.state = { count: 1 }; } componentDidMount() { setTimeout(() => { console.log('count:', this.state.count); // count: 1 this.setState({ count: 2 }); console.log('count:', this.state.count); // count: 2 }, 0); } render() { return ( <div className="App"> Count: {this.state.count} </div> ) } }
在 setTimeout() 中使用 setState() 也会立即更新 state 值。
setState 只是一个普通的函数,并没有同步/异步的说法。我们平时所说的同步/异步是指在调用它之后是否会立即更新对应的 state。
React 为了 DOM 渲染的性能可能会延迟 state 更新,所以表现出了 state 的“异步”更新效果。
对于 setTimeout,原生事件监听器等场景则会立即更新 state 值,表现出了“同步”的效果。
网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
本帖最后由 pkulixi 于 2014-6-3 10:54 编辑 日志里提醒的消息如下: 2014/06/01 11:00:10 T x
本帖最后由 Huan 于 2014-11-30 12:56 编辑 几兆的文件,同步了一个早上,还没同步完 一个早上只同步了94.2KB
rt,快盘无法同步其它物理卷的文件。一下是提示:
快盘的状态总是“正在扫描更改”,重新装过也不行。很是纠结,在办公室里编辑完文档之后,回家还得手动到网站上下载文档,无法总动同步。求各位大大的帮助! log日志如下: 2014/06/28 21:12
以前有个版本是有这个功能的,非常好用。 我的两台电脑都是ubuntu ,都装有快盘,局域网同步功能相当于U盘,不过更加方便。 不知道后面的版本为什么取消了这个功能,很是遗憾。 建议恢复,并且添
本帖最后由 blue8king 于 2014-7-1 15:08 编辑 金山快盘 14.04 64Bit 版本,安装后设置代理好像没有作用,无法登录。 公司内部有网络限制,无法直接登录外部网
如题。
版本:kuaipan4uk 2.0.0.2 启动后一直提示 正在扫描更改 信息输出: $ kuaipan4uk Indicator::
金山快盘 for Ubuntu Kylin 版总得说来还是个非常不错的客户端,但有我觉得有两个功能需要加进去。一是只能同步快盘文件夹~/KuaiPan/下的文件和目录,如果是其它目录的文件就只能用l
刚装了kuaipan4uk官方的,14.04 64bit的,系统是14.04 64bit。可是它一直在转,只把文件夹给我同步完成了,里面的文件一个都没有,都2天了,还是那样。求问怎么回事? 我觉得不
扫一扫关注公众号
添加我为好友,拉您入交流群!
请使用微信扫一扫!