React扩展知识点
setState
更新状态的两种写法:
- 对象式:
setState(stateChange, [callback])
- stateChange为状态改变对象(该对象可以体现出状态的更改)
- callback是可选的回调函数,它在状态更新完毕,并且界面渲染之后才被调用
- 函数式:
setState(updater, [callback])
- updater为返回stateChange对象的函数
- updater可以接收到state和props
- callback是可选的回调函数,它在状态更新完毕,并且界面渲染之后才被调用
案例演示 我们还是用之前的求和案例来做演示,基础代码如下:
import React, { Component } from 'react'
export default class SetStateDemo extends Component {
state = {count: 0}
render() {
return (
<div>
<h1>当前求和为:{this.state.count}</h1>
<button onClick={this.add}>点我+1</button>
</div>
)
}
}
对象式
callback
函数式是非必填的参数,由于setState
是异步的,当我们在设置完成状态之后,如果需要使用更新后的状态做一些其他的操作,可以使用该参数,直接在当前代码块中查询状态的话,可能会查询到更新之前的状态值,例如:
// 对象式 setState
add = () => {
const {count} = this.state
this.setState({count: count + 1}, () => {
console.log('callback: ', this.state.count)
})
console.log('验证state异步更新', this.state.count)
}
函数式
在函数式的函数中,可以拿到state
和props
。
// 函数式 setState
add = () => {
this.setState((state, props) => {
return {count: state.count + 1}
})
}
小结:
-
对象式的
setState
是函数式的setState
的简写方式 -
使用原则: 1)如果新状态不依赖于原状态 --- 使用对象方式
2)如果新状态依赖于原状态 --- 使用函数方式
3)如果需要在
setState()
执行后获取最新的状态数据,要在第二个callback
函数中读取
lazyLoad
路由组件应该是使用懒加载最多的组件了,我们一个项目中有几十上百个组件都是很常见的事情,如果每次请求,都要将所有的组件加载出来,哪怕你根本就用不上,那样会严重的影响到用户的体验感的。以前面讲解过的路由组件案例为例:
import React, { Component } from 'react'
import { NavLink, Routes, Route } from 'react-router-dom'
import Home from './Home'
import About from './About'
export default class LazyLoadDemo extends Component {
render() {
return (
<div id='root'>
<div>
<div className='row'>
<div className='col-xs-offset-2 col-xs-8'>
<div className='page-header'>
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className='row'>
<div className='col-xs-2 col-xs-offset-2'>
<div className='list-group'>
<NavLink className='list-group-item' to='/about'>About</NavLink>
<NavLink className='list-group-item' to='/home'>Home</NavLink>
</div>
</div>
<div className='col-xs-6'>
<div className='panel'>
<div className='panel-body'>
<Routes>
<Route path='/about' element={<About/>}/>
<Route path='/home' element={<Home/>}/>
</Routes>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
}
当我们打开网页时,还没点击About
或者是Home
按钮,它就已经先帮我们将资源加载好了,如下图所示:
我们点击清除按钮,再点击About
按钮,可以看到没有发出任何的请求
我们需要的效果应该是,当用户点击了某个路由导航,我们才去发起请求,哪怕有一百个,一千个,用户只点击了两三个,那么发出的请求就只有两三个,而不会缓存很多用不上的。
要实现懒加载,我们需要借助react
框架的lazy
函数,具体使用方式如下:
- 引入
lazy
import React, { Component, lazy } from 'react'
- 修改引入路由组件的方式,
lazy
函数的入参也是一个函数,我们在函数回调中使用import()
的方式引入组件
const Home = lazy(() => import('./Home'))
const About = lazy(() => import('./About'))
调整好了,我们看看效果:
哦吼,报错了,错误提示的大概意思就是说,选择了懒加载,当我们网速过慢的时候,选中的路由组件还未加载出来,需要有一个兜底的组件来展示。
- 引入
Suspense
,指定一个兜底的组件,将其余的路由组件包裹起来
import React, { Component, lazy, Suspense } from 'react'
<Suspense fallback={<h1>Loading...</h1>}>
<Routes>
<Route path='/about' element={<About/>}/>
<Route path='/home' element={<Home/>}/>
</Routes>
</Suspense>
通过控制台的设置,将Online
模式调整为Slow 3G
模式,我们可以看到点击按钮时,由于网络延迟,它会先展示出兜底组件的信息,然后再调整到我们请求的组件。
本文正在参加「金石计划 . 瓜分6万现金大奖」