
React(十一)- React拓展:Fragment、Context及PureComponent
可以使用
项目结构:
发布日期:2021-05-07 14:50:27
浏览次数:25
分类:技术文章
本文共 5034 字,大约阅读时间需要 16 分钟。
React(十一)- React拓展:Fragment、Context及PureComponent
一. Fragment拓展
案例如下:
jsx语法中,render()
里面最外层的标签,同级的不能有两个,如下

Fragment
包起来,来解决上述问题: 
二. Context拓展
Context,一种组件通信方式,常用于祖组件
和子类组件
之间的通信。
案例如下:
首先,页面效果如图:

Demo
组件: import React, { Component } from 'react'import './index.css'const MyContext = React.createContext()const { Provider, Consumer } = MyContextexport default class A extends Component { state = { username: 'tom', age: 18 } render() { const { username, age } = this.state return () }}class B extends Component { render() { return (我是A组件
我的用户名是:{ username}
) }}// 类式组件的用法// class C extends Component { // // 声明接收context// static contextType = MyContext// render() { // const { username, age } = this.context// return (//我是B组件
//// )// }// }// 函数式组件的用法,必须使用到Consumer标签function C() { return (我是C组件
//我从A组件中接收到的用户名是:{username}
//我从A组件中接收到的年龄是:{age}
//)}我是C组件
我从A组件中接收到的用户名是:
{ value => `${ value.username},年龄是${ value.age}`}
index.css
文件:
.parent{ width: 500px; background-color: orange; padding: 8px;}.child{ width: 100%; background-color: skyblue; padding: 8px;}.grand{ width: 400px; background-color: gray; padding: 10px;}
从代码结构来看,A是父类,B是A的子类,C是B的子类,哪怕B没有传递对应的属性,C依旧可以获取到A类的值。
2.1 总结
-
创建
Context
容器对象:const xxx= React.createContext()
-
渲染子组件时,外面包裹
xxx.Provider
标签,通过value
属性给后代组件传递数据:
<子组件 />
- 后代组件读取数据:并且只要用
xxx.Provider
包裹的一个子组件,那么该子组件以及其后代都能够直接获取到对应的数据,只需要声明接收context
即可。
//第一种方式:仅适用类组件 // 声明接收context,contextType命名是固定的static contextType = xxxContext // 读取context中的value数据this.context //第二种方式: 函数组件与类组件都可以{ value => ( // value就是context中的value数据 要显示的内容 ) }
三. PureComponent拓展
这一小节主要来说说组件的优化,其实Component
有2个问题
-
只要执行
setState()
,即使不改变状态数据,。组件也会重新调用render()
函数,效率低。 -
只当前组件重新
render()
,就会自动重新渲染子组件, 纵使子组件没有用到父组件的任何数据,效率低
效率高的情况是怎么样的呢?就是:只有当组件的state
或props
数据发生改变时才重新调用render()
,即不会收父组件以及setState()
方法的影响。
案例1:
import React, { Component } from 'react'import './index.css'export default class Parent extends Component { state = { carName: '奔驰' } changeCar = () => { this.setState({ carName: '宝马' }) } render() { console.log('Parent----render') const { carName} = this.state return () }}class Child extends Component { render() { console.log('Child----render') return (我是Parent组件
车名:{ carName} ) }}我是Child组件
我接收到的车是:{ this.props.carName}
页面效果:

点击换车
按钮后可以发现:子组件也重新调用了render()
进行了渲染。
那么如何对上述问题进行修改呢?
3.1 修改方案1
重写shouldComponentUpdate()
方法:
import React, { Component } from 'react'import './index.css'export default class Parent extends Component { state = { carName: '奔驰' } changeCar = () => { this.setState({ carName: '宝马' }) } render() { console.log('Parent----render') const { carName } = this.state return () }}class Child extends Component { shouldComponentUpdate(nextProps, nextState) { return !this.props.carName === nextProps.carName } render() { console.log('Child----render') return (我是Parent组件
车名:{ carName} ) }}我是Child组件
我接收到的车是:{ this.props.carName}
3.2 修改方案2
引用PureComponent
import React, { PureComponent } from 'react'import './index.css'export default class Parent extends PureComponent { state = { carName: '奔驰' } changeCar = () => { this.setState({ carName: '宝马' }) } render() { console.log('Parent----render') const { carName } = this.state return () }}class Child extends PureComponent { render() { console.log('Child----render') return (我是Parent组件
车名:{ carName} ) }}我是Child组件
我接收到的车是:{ this.props.carName}
页面效果:

点击换车
按钮后可以发现:子组件并没有调用render()
。

原理如下:
PureComponent
重写了shouldComponentUpdate()
,,只有state
或props
数据有变化才返回true
注意:
- 只是进行
state
和props
数据的浅比较,如果只是数据对象内部数据变了,返回false
。 - 不要直接修改
state
数据,,而是要产生新数据。
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年03月20日 11时32分40秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Decision tree(决策树)算法初探
2019-03-05
《Unity3D/2D游戏开发从0到1(第二版本)》 书稿完结总结
2019-03-05
sctf_2019_easy_heap
2019-03-06
Eclipse 创建 Maven 项目
2019-03-06
AT 杂题泛做
2019-03-06
StringBuilder拼接字符串,“,”在前还是在后问题
2019-03-06
给asterisk1.8.7添加menuselct选项
2019-03-06
组合模式
2019-03-06
PyQt5之音乐播放器
2019-03-06
css居中方法与双飞翼布局
2019-03-06
Redis进阶实践之十八 使用管道模式提高Redis查询的速度
2019-03-06
SQL注入
2019-03-06
XCTF-upload1
2019-03-06
LeetCode 题解 | 1. 两数之和
2019-03-06
#2036:改革春风吹满地
2019-03-06
MPI Maelstrom POJ - 1502 ⭐⭐ 【Dijkstra裸题】
2019-03-06