Assumptions:
There is a complex component tree in the project:
Context value passing purpose
Data is passed top-down (from parent to child) via props, but this is extremely cumbersome for certain types of props (e.g. locale preferences, UI themes) that are important to the application Required by many components in .
Context passing value advantages
Context provides a way to share such values between components without having to explicitly pass props through the layers of the component tree.
When to use Context
Context is designed to share data that is "global" to a tree of components, such as the currently authenticated user, theme, or preferred language.
ContextAPI
1.React.createContext API
功能:
创建一个 Context 对象。
//代码
//创建context对象的
import React from 'react'
let context=React.createContext();
export default context;
2.Context.Provider API
功能:
Provider 是context对象提供的内置组件 限定在某个作用域中使用context传值。
限定作用域传值。
3.Context.Consumer
context对象的内置组件
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
作用:监听订阅的context变更,
这个函数接收当前的 context 值,返回一个 React 节点。
Project case: theme color switching.
1.创建context.js文件
创建context对象 用来做context传值。
//创建context对象的
import React from 'react'
export default React.createContext();
2。使用context找到限定范围使用内置组件Provider
{/* 使用Provider 内置组件限定context范围 */}
{/* value 必填 context传递的值 */}
<ThemeContext.Provider>
<div className="Admin">
<div className="LeftMenu">
<LeftMenu></LeftMenu>
</div>
<div className="RightContent">
<div className="RightContent-top">
<TopHeader></TopHeader>
</div>
<div className="RightContent-bottom">
<Dashborder></Dashborder>
</div>
</div>
</ThemeContext.Provider>
The browser reports an error:
3.在使用context的组件中进行订阅
左侧菜单组件
import React, { Component } from "react";
console.log(Component);
//引入context对象
import ThemeContext from "../components/context";
class LeftMenu extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<>
<div>左侧菜单</div>
</>
);
}
}
//class类组件存在contextType 绑定context对象
LeftMenu.contextType = ThemeContext;
Use after binding the context in the component:
Means to subscribe to the internals of the context component using this.context to obtain.
render() {
//获取context
let theme = this.context;
return (
<>
<div className={theme}>左侧菜单</div>
</>
);
}
Fixed subject changed to dynamic subject
修改了context文件代码
//定义默认主体色
export const themes = {
dark: {
backgroundColor: "#000",
color: "#fff",
},
light: {
backgroundColor: "#fff",
color: "#000",
},
};
//创建context对象的
import React from "react";
export const ThemeContext = React.createContext();
app.js文件中获取主题,动态切换主题。使用主题变量
constructor(props) {
super(props);
this.state = {
//将固定的主体设置为state状态
themeType: "dark",//控制主体切换
nowTheme: themes["dark"],//获取当前默认主体
};
}
render() {
//解构获取
let { nowTheme } = this.state;
return (
<>
{/* 使用Provider 内置组件限定context范围 */}
{/* value 必填 context传递的值 */}
<ThemeContext.Provider value={nowTheme}>
Use this.context in the subscription component to get the subscription
render() {
//获取context
let { backgroundColor, color } = this.context;
return (
<>
//直接绑定行内css
<div style={
{ backgroundColor: backgroundColor, color: color }}>
左侧菜单
</div>
</>
);
}
The user clicks the buttons of other components to modify the theme to change the theme
注意:不能直接使用this.context修改变量值
//可以在provider组件上 value中携带修改函数传递。在订阅组件中获取修改方法,执行反向传递值。
//修改主题变量方法
changeTheme(type) {
console.log("测试", type);
this.setState({ themeType: type, nowTheme: themes[type] });
}
render() {
//解构获取
let { nowTheme } = this.state;
return (
<>
{/* 使用Provider 内置组件限定context范围 */}
{/* value 必填 context传递的值 */}
<ThemeContext.Provider
value={
{ ...nowTheme, handler: this.changeTheme.bind(this) }}
>
<div className="Admin">
<div className="LeftMenu">
<LeftMenu></LeftMenu>
</div>
<div className="RightContent">
<div className="RightContent-top">
<TopHeader></TopHeader>
</div>
<div className="RightContent-bottom">
<Dashborder></Dashborder>
</div>
</div>
</div>
</ThemeContext.Provider>
</>
);
//在订阅组件中直接使用
//修改主题的方法
change(themeType) {
console.log(themeType);
//获取provider传递方法
let { handler } = this.context;
handler(themeType);
}
render() {
let { themeButton } = this.state;
return (
<>
<div>
<span>主题色:</span>
<div>
{/* 控制左侧菜单和上header背景色 */}
{themeButton.map((item, index) => {
return (
<button key={index} onClick={this.change.bind(this, item.type)}>
{item.name}
</button>
);
})}
</div>
</div>
</>
);
Add custom colors
{/* 颜色选择器 */}
背景色:
<input
type="color"
name="selectbgColor"
value={selectbgColor}
onChange={this.changeColor.bind(this)}
/>
字体色:
<input
type="color"
name="selectColor"
value={selectColor}
onChange={this.changeColor.bind(this)}
/>
<button onClick={this.yesHandler.bind(this)}>确认</button>
//代码区域操作事件向父级传递参数
//确认修改
yesHandler() {
let { myhandler } = this.context;
let { selectbgColor, selectColor } = this.state;
console.log(selectbgColor, selectColor);
myhandler(selectbgColor, selectColor);
}
Add monitoring context changes
{/*监听context value值*/}
<ThemeContext.Consumer>
{(value) => {
let { backgroundColor, color } = value;
return (
<>
<span>背景色:{backgroundColor}</span>
<span>文字色:{color}</span>
</>
);
}}
</ThemeContext.Consumer>
class component life cycle
Component life cycle explanation: the whole process from component initialization to destruction.
Three types of life cycle:
Mounting: inserted into the real DOM
Updating: is being re-rendered
Unmounting: moved out of the real DOM
第一个阶段:
代码演示第一个阶段初始化挂载阶段
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {};
console.log("初始化");
}
componentDidMount() {
console.log("挂载完成");
}
render() {
console.log("渲染");
return (
<>
<div>测试</div>
</>
);
}
}
export default App;
Added pre-mount cycle
UNSAFE_componentWillMount() {
console.log("挂载之前");
}
//18.x 版本中UNSAFE_ 前缀
第二个阶段:更新阶段
能触发类组件更新 props state
Added pre-update cycle
componentWillUpdate() {
console.log("更新之前");
}
第三阶段卸载:
//卸载周期
componentWillUnmount() {
console.log("组件卸载");
}
Common cycle:
After the test is completed: Version 18 directly uses the above three cycles.
react推荐网络请求在componentDidMount
卸载清除副作用 componentWillUnmount
Confirm whether the current component update cycle
//确认是否更新周期
//必须带返回值 true false
//提升性能
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log(nextProps);
if (nextProps.name == this.props.name) return false;
else return true;
}
不写该周期默认是执行更新
1.componentWillMount() - 在染之前执行,在客户端和服务器端都会执行.
2.componentDidMount() - 是挂在完成之后执行一次
3.componentWillReceiveProps() - 当从父类接收到 props 并且在调用另一个渲染器器之前调用。4.shouldComponentUpdatel) -根据特定条件返回 true 或 false如果你希望更新组件,请返回true 否则返它返回 false。
5.componentWillUpdate() - 是当前组件state和props发生变化之前执行
6.componentDidUpdate()-是当前组件state和props发生变化执行
7.componentWillUnmount0) - 从 DOM 卸载组件后调用。用于清理内存空间