一、Context
1. 理解
一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信
2. 使用
1) 创建Context容器对象:
const XxxContext = React.createContext()
2) 渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据:
<xxxContext.Provider value={数据}>
子组件
</xxxContext.Provider>
3) 后代组件读取数据:
//第一种方式:仅适用于类组件
static contextType = xxxContext // 声明接收context
this.context // 读取context中的value数据
//第二种方式: 函数组件与类组件都可以
<xxxContext.Consumer>
{
value => ( // value就是context中的value数据
要显示的内容
)
}
</xxxContext.Consumer>
3. 注意
在应用开发中一般不用context, 一般都用它封装react插件
4. 代码
1 import React, { Component } from 'react'
2 import './index.css'
3
4 //创建Context对象
5 const MyContext = React.createContext()
6 const {Provider,Consumer} = MyContext
7 export default class A extends Component {
8
9 state = {username:'tom',age:18}
10
11 render() {
12 const {username,age} = this.state
13 return (
14 <div className="parent">
15 <h3>我是A组件</h3>
16 <h4>我的用户名是:{username}</h4>
17 <Provider value={{username,age}}>
18 <B/>
19 </Provider>
20 </div>
21 )
22 }
23 }
24
25 class B extends Component {
26 render() {
27 return (
28 <div className="child">
29 <h3>我是B组件</h3>
30 <C/>
31 </div>
32 )
33 }
34 }
35
36 /* class C extends Component {
37 //声明接收context
38 static contextType = MyContext
39 render() {
40 const {username,age} = this.context
41 return (
42 <div className="grand">
43 <h3>我是C组件</h3>
44 <h4>我从A组件接收到的用户名:{username},年龄是{age}</h4>
45 </div>
46 )
47 }
48 } */
49
50 function C(){
51 return (
52 <div className="grand">
53 <h3>我是C组件</h3>
54 <h4>我从A组件接收到的用户名:
55 <Consumer>
56 {value => `${value.username},年龄是${value.age}`}
57 </Consumer>
58 </h4>
59 </div>
60 )
61 }
二、optimize组件优化
1. Component的2个问题
1)只要执行setState(),即使不改变状态数据, 组件也会重新render()
2) 只当前组件重新render(), 就会自动重新render子组件 ==> 效率低
2. 效率高的做法
只有当组件的state或props数据发生改变时才重新render()
3. 原因
Component中的shouldComponentUpdate()总是返回true
4. 解决
方法1:
重写shouldComponentUpdate()方法
比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
方法2:
使用PureComponent
PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
注意:
只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化
5. 代码
1 import React, { PureComponent } from 'react'
2 import './index.css'
3
4 export default class Parent extends PureComponent {
5
6 state = {carName:"奔驰c36",stus:['小张','小李','小王']}
7
8 addStu = ()=>{
9 /* const {stus} = this.state
10 stus.unshift('小刘')
11 this.setState({stus}) */
12
13 const {stus} = this.state
14 this.setState({stus:['小刘',...stus]})
15 }
16
17 changeCar = ()=>{
18 //this.setState({carName:'迈巴赫'})
19
20 const obj = this.state
21 obj.carName = '迈巴赫'
22 console.log(obj === this.state);
23 this.setState(obj)
24 }
25
26 /* shouldComponentUpdate(nextProps,nextState){
27 // console.log(this.props,this.state); //目前的props和state
28 // console.log(nextProps,nextState); //接下要变化的目标props,目标state
29 return !this.state.carName === nextState.carName
30 } */
31
32 render() {
33 console.log('Parent---render');
34 const {carName} = this.state
35 return (
36 <div className="parent">
37 <h3>我是Parent组件</h3>
38 {this.state.stus}
39 <span>我的车名字是:{carName}</span><br/>
40 <button onClick={this.changeCar}>点我换车</button>
41 <button onClick={this.addStu}>添加一个小刘</button>
42 <Child carName="奥拓"/>
43 </div>
44 )
45 }
46 }
47
48 class Child extends PureComponent {
49
50 /* shouldComponentUpdate(nextProps,nextState){
51 console.log(this.props,this.state); //目前的props和state
52 console.log(nextProps,nextState); //接下要变化的目标props,目标state
53 return !this.props.carName === nextProps.carName
54 } */
55
56 render() {
57 console.log('Child---render');
58 return (
59 <div className="child">
60 <h3>我是Child组件</h3>
61 <span>我接到的车是:{this.props.carName}</span>
62 </div>
63 )
64 }
65 }