什么是context
首先大家要明白一些概念,首先是 react 组件间传递数据是通过 props 向下(也就是想子组件传递),是单向传递的,从父级一层一层地通过 props 地向下传递到子子孙孙,有的时候我们组件一层一层的嵌套多层,这样这种方式一层一层传递麻烦,我们可不可以进行跃层传递,这就会用到 context。
组件化的优点
- 增强代码重用性,提高开发效率
- 简化操作步骤,提升整个项目的可维护性
- 便于协同开发
- 注意点:降低耦合性
组件的跨层级通信:context
类似于vue中的provider inject
快速开始
# 生成一个react项目
npx create-react-app context
# 进入并启动项目
cd context
npm start
Context API
1. React.createContext
创建context对象
// 新建Context.js
import React from "react";
export const Context=React.createContext();
2. Context.Provider
父级创建provider传递参数
<Context.Provider value={theme}>
<ContextTypePage/>
</Context.Provider>
3. 子组件消费(3种途径)
- contextType
//传递一个参数的情况
import React, { Component } from 'react'
import {Context} from "../Context"
export default class ContextTypePage extends Component {
static contextType=Context;
render() {
const {themeColor}=this.context;
console.log("contextType",this.context)
return (
<div className="border">
<span>我是ContextTypePage页面</span>父级传过来的颜色是——{themeColor}
</div>
)
}}
//传递两个参数的情况
import React, { Component } from 'react'
import {Context,UserContext} from "../Context"
export default class ContextTypePage extends Component {
static contextType=Context;
static contextType=UserContext;
render() {
const {themeColor,name}=this.context;//有多个参数后面的会覆盖前面的
return (
<div className="border">
<span>我是ContextTypePage页面</span>
父级传过来的是——{themeColor}
<p>传过来的第二个参数:{name}</p>
</div>
)
}}
注意⚠️:**contextType只可以用在类组件中,多个参数不适合用,后面的会覆盖前面的**
传递一个参数效果如图一:
传递两个参数效果如图二:
- useContext
//传递一个参数情况
import React from 'react'
import {Context}from '../Context'
export default function useContextPage() {
const theme=React.useContext(Context)
return (
<div className="border">
<span>我是useContextPage页面</span>
父级传过来的颜色是——{theme.themeColor}
</div>
)
}
//传递两个参数情况
import React from 'react'
import {Context,UserContext}from '../Context'
export default function useContextPage(props) {
const theme=React.useContext(Context)
const user=React.useContext(UserContext)
return (
<div className="border">
<span>我是useContextPage页面</span>
父级传过来的是——{theme.themeColor}
<p>传过来的第二个参数:{user.name}</p>
</div>
)
}
注意⚠️:useContext只可以用在函数组件中或者自定义hook,且第二个参数不会覆盖第一个
传递一个参数效果图如下: 传递两个参数效果图如下:
- Consumer
//传递一个参数
import React, { Component } from 'react'
import { Context } from '../Context'
export default class ConsumerPage extends Component {
render() {
return (
<div className="border">
我是ConsumerPage页面
<Context.Consumer>
{
theme=>{
return <div>页面父组件传过来的颜色是——{theme.themeColor}
</div>
}
}
</Context.Consumer>
</div>
)
}
}
//传递两个参数
import React, { Component } from 'react'
import { Context,UserContext } from '../Context'
export default class ConsumerPage extends Component {
render() {
return (
<div className="border">
我是ConsumerPage页面
<Context.Consumer>
{
theme=>{
return <div>页面父组件传过来的是——{theme.themeColor}
<UserContext.Consumer>
{
user=><p>我是传过来第二个参数——{user.name}</p>
}
</UserContext.Consumer>
</div>
}
}
</Context.Consumer>
</div>
)
}
}
注意⚠️:不限制函数组件还是类组件用法比较复杂,也不会存在后者覆盖前者
传递一个参数效果图如下: 传递两个参数效果图如下: