Context
提供了一种方式,能够让数据在组件树中传递时不必一级一级的手动传递。
一般情况下,数据在组件中,要一级一级的传递,单向数据流,比如Parent组件中的theme值,需要在Item组件中使用,就需要我们从Parent中向下传递, 但当我们有了Context后,我们就不需要一级一级传递了。
Parent(theme=red)
List(theme=red)
Item(theme=red)
ThemeContext.Provider value={'red'}
List
ThemeContext.Customer (theme) => { theme }
具体如何使用呢,看下面例子:
import React, { createContext } from 'react';
// 创建Context的唯一方法
const ThemeContext = createContext()
class App extends React.Component {
render () {
return (
// 使用 Context.Provider 包裹后续组件,value指定值
<ThemeContext.Provider value={'red'}>
<Middle></Middle>
</ThemeContext.Provider>
)
}
}
class Bottom extends React.Component {
render () {
return (
// Context.Consumer Consumer消费者使用Context的值
// 但子组件不能是其他组件,必须渲染一个函数,函数的参数就是Context的值
<ThemeContext.Consumer>
{
theme => <h1>ThemeContext的值为{theme}</h1>
}
</ThemeContext.Consumer>
)
}
}
class Middle extends React.Component {
render () {
return <Bottom></Bottom>
}
}
export default App;
当 Provider
提供的值更改时,Consumer
必须重新渲染!
import React, { createContext } from 'react';
// 创建Context的唯一方法
const ThemeContext = createContext()
class App extends React.Component {
state = {
theme: 'red'
}
render () {
const { theme } = this.state
return (
// 使用 Context.Provider包裹后续组件,value指定值
<ThemeContext.Provider value={theme}>
{/* 当Context的Provider值更改时,Consumer 的值必须重新渲染 */}
<button onClick={() => {this.setState({ theme: 'yellow'})}}>按钮</button>
<Middle></Middle>
</ThemeContext.Provider>
)
}
}
class Bottom extends React.Component {
render () {
return (
// Context.Consumer Consumer消费者使用Context的值
// 但子组件不能是其他组件,必须渲染一个函数,函数的参数就是Context的值
<ThemeContext.Consumer>
{
theme => <h1>ThemeContext的值为{theme}</h1>
}
</ThemeContext.Consumer>
)
}
}
class Middle extends React.Component {
render () {
return <Bottom></Bottom>
}
}
export default App;
当出现多个Context
的时候,应该如何使用呢?
import React, { createContext } from 'react';
// 创建Context的唯一方法
const ThemeContext = createContext()
const SizeContext = createContext()
class App extends React.Component {
state = {
theme: 'red',
size: 'small'
}
render () {
const { theme, size } = this.state
return (
// 使用Context.Provider包裹后续组件,value指定值
<ThemeContext.Provider value={theme}>
{/* 当出现多个Context的时候,只需要将Context.Provider嵌套即可 */}
<SizeContext.Provider value={size}>
{/* 当Context的Provider值更改时,Consumer的值必须重新渲染 */}
<button onClick={() => {this.setState({ theme: 'yellow', size: 'big'})}}>按钮</button>
<Middle></Middle>
</SizeContext.Provider>
</ThemeContext.Provider>
)
}
}
class Bottom extends React.Component {
render () {
return (
// Context.Consumer Consumer消费者使用Context得值
// 但子组件不能是其他组件,必须渲染一个函数,函数的参数就是Context的值
// 当出现多个Consumer的时候,进行嵌套,每个Consumer的子组件必须是一个函数,即可
<ThemeContext.Consumer>
{
theme => (
<SizeContext.Consumer>
{
size => (<h1>ThemeContext 的 值为 {theme}; SizeContext 的值为 {size}</h1>)
}
</SizeContext.Consumer>
)
}
</ThemeContext.Consumer>
)
}
}
class Middle extends React.Component {
render () {
return <Bottom></Bottom>
}
}
export default App;
当Consumer
向上找不到 Provider
的时候,怎么办?react
并不会报错,只不过取不到值而已。所以,创建 Context
的时候 createContext
可以传入默认值,当找不到 Provider
的时候,就会显示默认值。
注意:context
类似于全局变量做法,会让组件失去独立性、复用起来更困难,不能滥用,但本身它一定有适合使用的场景,具体看情况使用。
contextType
可以简化 context
的使用,不使用 consumer
也可以共享变量。
具体看下面例子
import React, { createContext } from 'react';
// 创建Context的唯一方法
const ThemeContext = createContext()
const SizeContext = createContext()
class App extends React.Component {
state = {
theme: 'red',
size: 'small'
}
render () {
const { theme, size } = this.state
return (
// 使用Context.Provider包裹后续组件,value指定值
<ThemeContext.Provider value={theme}>
{/* 当出现多个Context的时候,只需要将Context.Provider嵌套即可 */}
<SizeContext.Provider value={size}>
{/* 当Context的Provider值更改时,Consumer的值必须重新渲染 */}
<button onClick={() => {this.setState({ theme: 'yellow', size: 'big'})}}>按钮</button>
<Middle></Middle>
</SizeContext.Provider>
</ThemeContext.Provider>
)
}
}
class Bottom extends React.Component {
// 声明静态变量,contextType 将 context 直接赋值于 contextType
static contextType = ThemeContext
render () {
// 在render函数中可以直接访问this.context获取共享变量,这样就可以不使用consumer
const theme = this.context
return (
// Context.Consumer Consumer消费者使用Context的值
// 但子组件不能是其他组件,必须渲染一个函数,函数的参数就是Context的值
// 当出现多个Consumer的时候,进行嵌套,每个Consumer的子组件必须是一个函数,即可
<div>
<h1>ThemeContext的值为{theme} </h1>
</div>
)
}
}
class Middle extends React.Component {
render () {
return <Bottom></Bottom>
}
}
export default App;
注意:contextType
只能在类组件中使用, 一个组件如果有多个 consumer
, contextType
只对其中一个有效,所以说,contextType 只能有一个!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://shq5785.blog.csdn.net/article/details/117734108
内容来源于网络,如有侵权,请联系作者删除!