Context
除了Redux第三方全局状态管理外 React本身也有Context上下文用于跨组件传递数据
当组件嵌套层级过多时 eg:app>test>test2
新建myCtx.js用于创建上下文对象
// myCtx.js
import React from 'react'
const ctx = React.createContext({
a: 1,
b: 2
}) // 此处填入的为默认数据
export default ctx
// app.js
import Test from './test.js' // 嵌套的子组件
import Ctx from './myCtx' // 引入的context上下文对象
export default function app () {
return (
// 通过 Ctx.Provider 组件来将上下文对象的数据传入到组件树中
// value的值为需要传入的值
// 如果没有使用 Ctx.Provider 组件 则在组件树中传入在myCtx.js定义的默认数据
<Ctx.Provider value={{ k: 1, f: 5 }}>
<div className='App'>
<h1>app根组件</h1>
<hr />
<Test></Test>
</div>
</Ctx.Provider>
)
}
// test.js 函数组件中
import Test2 from './test2' // 嵌套的子组件
import Ctx from './myCtx' // 引入的context上下文对象
import { useContext } from 'react'; // 解构出useContext hook
export default function Test () {
const c = useContext(Ctx) // 将上下文对象传入hook中调用 返回值即为数据
console.log('函数组件使用context', c);
return (
<div>
<h1>Test1 组件</h1>
<hr />
<Test2></Test2>
</div>
)
}
// test2.js 类组件中
import React, { Component } from 'react'
import Ctx from './myCtx'
export default class Test2 extends Component {
render () {
console.log('类组件中使用context', this.context);
return (
<div>
<h1>Test2组件</h1>
</div>
)
}
}
// 把上下文对象 赋值给Test2的静态属性 contextType
// 就可以让类组件的内部 用过this.context来得到全局供应的数据
Test2.contextType = Ctx
新版Context
生产者消费者模式
先定义全局context对象
import React from 'react'
const GlobalContext = React.createContext()
export default GlobalContext
根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)
<GlobalContext.Provider
value={{
background: 'green',
color: 'white',
content:this.state.content,
methodA:this.changeStateByChildren
}}
>
</GlobalContext.Provider>
传入的value为根context对象的值,如果是动态的,使用状态管理
组件引入GlobalContext并调用context,使用GlobalContext.Consumer(消费者)
<GlobalContext.Consumer>
{
context => {
return (
<div>
<h1 style={{background: context.background, color: context.color}}>
{context.content}
</h1>
<Input methodA = {context.methodA} value={context.content}></Input>
</div>
)
}
}
</GlobalContext.Consumer>
GlobalContext.Consumer内必须是回调函数,改变context,通过context方法改变根组件状态
注:
当需要修改上下文对象中的数据时 只能通过定义属性以及修改属性的方式 来进行修改
import Test from './test.js'
import Ctx from './myCtx'
import { useState } from 'react'
export default function App () {
const [c, setC] = useState(1)
return (
<Ctx.Provider value={{ k: 1, f: 5, c, setC }}> // 将属性以及修改属性的方法传入组件树 来进行状态修改
<div className='App'>
<h1>app根组件</h1>
<hr />
<Test></Test>
</div>
</Ctx.Provider>
)
}