创建context
//creatContext.js
import React from 'react'
export const NameContext = React.createContext();
export const AgeContext = React.createContext();
导入创建的context 并使用provider嵌套需要消费的组件
//主要显示的组件
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import ClassChild from './classChild'
export default class index extends Component {
state = {
name: "张三",
age: 18
}
render() {
const { name, age } = this.state;
return (
<NameContext.Provider value={name}>
<AgeContext.Provider value={age}>
<ClassChild />
</AgeContext.Provider>
</NameContext.Provider>
)
}
}
再导入创建的context 并使用静态类方法contextType接收
//classChild.js
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
export default class child extends Component {
static contextType = NameContext
static contextType = AgeContext
render() {
console.log(this.context)
return (
<div>
</div>
)
}
}
这里使用两个context接收是因为 class组件静态方法只可接收一个context,当然或许回想传一个对象其他值往里面塞 但是这个差异一定要知道
同上引入创建context文件夹
主文件
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import FunChild from './funChild'
export default class index extends Component {
state = {
name: "张三",
age: 18
}
render() {
const { name, age } = this.state;
return (
<NameContext.Provider value={name}>
<AgeContext.Provider value={age}>
<FunChild />
</AgeContext.Provider>
</NameContext.Provider>
)
}
}
子组件
import { useContext } from 'react'
import { NameContext, AgeContext } from './creatContext'
export default function FunChild() {
const name = useContext(NameContext)
const age = useContext(AgeContext)
return (
<div>
{name}
{age}
</div>
)
}
在函数组件中使用usecontext接收毫无疑问是可以接收两个的 因为我们可以用两个api去接收
Consumer是类组件 函数组件都可以使用的 因为是createContext中的api
主组件:
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import ClassChild from './classChild'
import FunChild from './funChild'
export default class index extends Component {
state = {
name: "张三",
age: 18
}
render() {
const { name, age } = this.state;
return (
<NameContext.Provider value={name}>
<AgeContext.Provider value={age}>
<FunChild />
<h1>类组件↓</h1>
<ClassChild />
</AgeContext.Provider>
</NameContext.Provider>
)
}
}
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
export default class child extends Component {
render() {
return (
<div>
<NameContext.Consumer>
{data => { return <p>类组件接收的name:{data}</p> }}
</NameContext.Consumer>
<AgeContext.Consumer>
{data => { return <p>类组件接收的age:{data}</p> }}
</AgeContext.Consumer>
<h3>下方是类组件中嵌套尝试</h3>
<NameContext.Consumer>
{name => {
return <div>
我的名字叫{name}
<AgeContext.Consumer>
{age => { return <p>我的年龄是{age}</p> }}
</AgeContext.Consumer>
</div>
}}
</NameContext.Consumer>
</div>
)
}
}
import React from 'react'
import { NameContext, AgeContext } from './creatContext'
export default function FunChild() {
return (
<div>
<NameContext.Consumer>
{name => { return <p>函数组件中的name: {name}</p> }}
</NameContext.Consumer>
<AgeContext.Consumer>
{age => { return <p>函数组件中的age: {age}</p> }}
</AgeContext.Consumer>
<h1>函数组件中的嵌套尝试↓</h1>
<NameContext.Consumer>
{name => {
return <div>
我的名字叫{name}
<AgeContext.Consumer>
{age => { return <p>我的年龄是{age}</p> }}
</AgeContext.Consumer>
</div>
}}
</NameContext.Consumer>
</div>
)
}
context会使用参考标志来决定何时进行渲染,这里有一个陷阱 如果是引用数据类型
例:
//传递的值是对象类型
<AgeContext.Provider value={{name: '对象'}}>
<FunChild />
<h1>类组件↓</h1>
<ClassChild />
</AgeContext.Provider>
这样在每次进行组件更新时对比原数据和新数据是否有差异 会做一个这样对比的操作
{name: '对象'} === {name: '对象'}
没有变量保存地址 引用地址是不同的 这样每次其他组件更新 这个provider下的组件都会判定数据不同 导致不必要的更新
这时候需要把数据提升到父组件中保存 改数据的引用地址 就比如存在state中