setState()方法异步执行
- setState()方法是异步执行的。
class App extends React.Component {
state = {
count: 0,
}
bianhua = () => {
this.setState({
count: this.state.count + 1
})
console.log("shuzi ",this.state.count);
}
render() {
return (<div>
<h1>数字:{this.state.count}</h1>
<button onClick={this.bianhua }>点击</button>
</div>
)
}
}
//渲染组件
ReactDOM.render(<App></App>, document.getElementById('root'))
上面的代码在每次执行setState()方法后打印了count的值。
可以看到每次页面数字的值已经变成1了,而打印的值还是之前的值0。所以说setState()方法是异步执行的
但是如果想要在执行玩setState()方法后就需要用到更新后的值该怎么办呢?
上面的方法肯定是不行的。
可以换一种setState的使用形式
bianhua = () => {
//使用这种形式,第二个形式参数为一个回调函数。
this.setState((state, props) => {
return {
count: state.count + 1
}
}, () => {
console.log("shuzi ", this.state.count)
})
}
通过这种形式可以在setState()调用结束后就拿到改变后的值。可以看到setState()中的第二个参数为一个回调函数。他在render重新完成渲染后执行。
- 在调用多次setState()方法时,只会执行一次render()触发页面渲染
组件更新解决重复渲染
在react 中,当父组件更新时,会更新所有的子组件。因此如果在更新父组件时,不想更新某一个子组件,可以通过使用钩子函数
shouldComponetUpdate()
- shouldComponetUpdate(nextProps,nextState)
- 返回值为true时表示更新组件,为false时表示不更新组件
- 执行时机:在组件重新渲染前执行
- 参数:
1.nextState在当前组件使用。可以通过nextState拿到更新后最新的值。通过this.state拿到更新前的值
2.nextProps在组件之间传参时使用。可以通过nextProps拿到更新后最新的值。通过this.props拿到更新前的值
纯组件解决重复渲染
纯组件就是将继承React.Componet更换为React.PureComponent
- PureComponent与React.Componet功能相似
- PureComponent内部自动实现了shouldComponetUpdate钩子函数,不需要手动比较。他的内部通过对比前后两次props和state的值,来决定是否重新渲染组件
纯组件内部对比的时shallow compare
浅层对比
- 对于值类型:比较两个值是否相同
- 对于引用类型:比较的时引用地址(引用类型需要创建新对象,否则每次都是比较的结果都是相同的,会导致组件不进行渲染)
React路由
- 使用
安装npm i react-router-dom
- 导入
import{BrowserRouter as Router,Route,Link } from 'react-router-dom'
- 使用Router包裹整个应用
- 使用Link作为导航菜单(路由入口)
- 使用Route组件配置路由规则和要展示的组件(路由出口)
编程式导航
- 通过Js代码来实现页面跳转
this.props.history.push('填写路径')
- history是React路由提供的,用于获取浏览器历史记录
- push(‘路径’):跳转到某个页面,参数表示要跳转的路径
- go(n):前进或后退到某个页面,参数n表示前进或后退页面的数量
匹配模式
默认情况是模糊匹配
可能出现的问题:会出现匹配多个路由。比如"/first" 会匹配到"/first、/first/s等等"
精确匹配
通过精确匹配解决模糊匹配出现的问题
- 给Route组件添加exact属性。可以让其变为精确匹配模式
- 精确匹配只有path和pathname完全相同时,才会展示路由