<></>
作用
可以不用必须有一个真实的DOM根标签了
import React, {Component, Fragment} from ‘react’
export default class Demo extends Component {
render() {
return (
)
}
}
理解
一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信
使用
- 创建Context容器对象:
const XxxContext = React.createContext()
- 渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据:
<xxxContext.Provider value={数据}>
子组件
</xxxContext.Provider>
- 后代组件读取数据:
//第一种方式:仅适用于类组件
static contextType = xxxContext // 声明接收context
this.context // 读取context中的value数据
//第二种方式: 函数组件与类组件都可以
<xxxContext.Consumer>
{
value => ( // value就是context中的value数据
要显示的内容
)
}
</xxxContext.Consumer>
注意
在应用开发中一般不用context, 一般都用它的封装react插件
index.css
index.jsx
- index.css
.parent {
width: 500px;
background-color: orange;
padding: 8px;
}
.child {
width: 100%;
background-color: skyblue;
padding: 8px;
}
.grand {
width: 100%;
background-color: gray;
padding: 8px;
}
- index.jsx
import React, {Component} from ‘react’
import ‘./index.css’
//创建Context对象
const MyContext = React.createContext()
const {Provider, Consumer} = MyContext
export default class A extends Component {
state = {username: ‘tom’, age: 18}
render() {
const {username, age} = this.state
return (
我是A组件
我的用户名是:{username}
<Provider value={{username, age}}>
)
}
}
class B extends Component {
render() {
return (
我是B组件
)
}
}
/* class C extends Component {
//声明接收context
static contextType = MyContext
render() {
const {username,age} = this.context
return (
我是C组件
我从A组件接收到的用户名:{username},年龄是{age}
)
}
} */
function C() {
return (
我是C组件
我从A组件接收到的用户名:
{value => ${value.username},年龄是${value.age}
}
)
}
Component的2个问题
- 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低
- 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低
效率高的做法
只有当组件的state或props数据发生改变时才重新render()
原因
Component中的shouldComponentUpdate()总是返回true
解决
- 办法1:
-
重写shouldComponentUpdate()方法
-
比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
- 办法2:
-
使用PureComponent
-
PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
- 注意:
-
只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
-
不要直接修改state数据, 而是要产生新数据
-
项目中一般使用PureComponent来优化
index.css
index.jsx
- index.css
.parent {
background-color: orange;
padding: 10px;
}
.child {
background-color: gray;
margin-top: 30px;
padding: 10px;
}
- index.jsx
import React, {PureComponent} from ‘react’
import ‘./index.css’
export default class Parent extends PureComponent {
state = {carName: “奔驰c36”, stus: [‘小张’, ‘小李’, ‘小王’]}
addStu = () => {
/* const {stus} = this.state
stus.unshift(‘小刘’)
this.setState({stus}) */
const {stus} = this.state
this.setState({stus: [‘小刘’, …stus]})
}
changeCar = () => {
//this.setState({carName:‘迈巴赫’})
const obj = this.state
obj.carName = ‘迈巴赫’
console.log(obj === this.state);
this.setState(obj)
}
/* shouldComponentUpdate(nextProps,nextState){
// console.log(this.props,this.state); //目前的props和state
// console.log(nextProps,nextState); //接下要变化的目标props,目标state
return !this.state.carName === nextState.carName
} */
render() {
console.log(‘Parent—render’);
const {carName} = this.state
return (
我是Parent组件
{this.state.stus}
我的车名字是:{carName}
点我换车
添加一个小刘
)
}
}
class Child extends PureComponent {
/* shouldComponentUpdate(nextProps,nextState){
console.log(this.props,this.state); //目前的props和state
console.log(nextProps,nextState); //接下要变化的目标props,目标state
return !this.props.carName === nextProps.carName
} */
render() {
console.log(‘Child—render’);
return (
我是Child组件
我接到的车是:{this.props.carName}
)
}
}
如何向组件内部动态传入带内容的结构(标签)?
Vue中:
使用slot技术, 也就是通过组件标签体传入结构
React中:
使用children props: 通过组件标签体传入结构
使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性
children props
xxxx
{this.props.children}
问题: 如果B组件需要A组件内的数据, ==> 做不到
render props
<A render={(data) => }>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data}
index.css
index.jsx
- index.css
.parent {
background-color: orange;
padding: 10px;
}
.a {
background-color: gray;
margin-top: 30px;
padding: 10px;
}
.b {
background-color: skyblue;
margin-top: 30px;
padding: 10px;
}
- index.jsx
import React, {Component} from ‘react’
import ‘./index.css’
import C from ‘…/1_setState’
export default class Parent extends Component {
render() {
return (
我是Parent组件
<A render={(name) => }/>
)
}
}
class A extends Component {
state = {name: ‘tom’}
render() {
console.log(this.props);
const {name} = this.state
return (
我是A组件
{this.props.render(name)}
)
}
}
class B extends Component {
render() {
console.log(‘B–render’);
return (
我是B组件,{this.props.name}
)
}
}
理解:
错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面
特点:
只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误
使用方式:
getDerivedStateFromError配合componentDidCatch
// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {
console.log(error);
// 在render之前触发
// 返回新的state
return {
hasError: true,
};
}
componentDidCatch(error, info) {
// 统计页面的错误。发送请求发送到后台去
console.log(error, info);
}
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
刷面试题
刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
-
前端字节跳动真题解析
-
【269页】前端大厂面试题宝典
,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-YqhyemYT-1710833725785)]
[外链图片转存中…(img-46NoNfpm-1710833725786)]
[外链图片转存中…(img-cIKc3FZR-1710833725786)]
[外链图片转存中…(img-B4K4LIMS-1710833725787)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-lmLYM8YF-1710833725787)]
刷面试题
刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
-
前端字节跳动真题解析
-
【269页】前端大厂面试题宝典
最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。