概述
◼ 在之前的开发中,我们要在组件中使用共享的Context有两种方式:
- 类组件可以通过 类名.contextType = MyContext方式,在类中获取context;
- 多个Context或者在函数式组件中通过 MyContext.Consumer 方式共享context;
context基础语法
使用场景:跨组件共享数据。
Context 作用:实现跨组件传递数据,而不必在每个级别手动传递 props,简化组件之间的数据传递过程
Context 对象包含了两个组件
- <Context.Provider value>:通过 value 属性提供数据。
- <Context.Consumer>:通过 render-props 模式,在 JSX 中获取 Context 中提供的数据。
注意:
- 如果提供了 Provider 组件,Consumer 获取到的是 Provider 中 value 属性的值。
- 如果没有提供 Provider 组件,Consumer 获取到的是 createContext(defaultValue) 的 defaultValue 值。
useContext使用
基本语法
作用:在函数组件中,获取 Context 中的值。要配合 Context 一起使用。
useContext Hook 与 <Context.Consumer> 的区别:获取数据的位置不同,
- <Context.Consumer>:在 JSX 中获取 Context 共享的数据。
- useContext:在 JS 代码中获取 Context 的数据。
解释:
- useContext 的参数:Context 对象,即:通过 createContext 函数创建的对象。
- useContext 的返回值:Context 中提供的 value 数据。
多个 context 的用法
以前的方式:
context/them-context.js
import React from 'react';
// 创建一个上下文
const ThemContext = React.createContext()
export default ThemContext
context/user-context.js
import React from 'react';
// 创建一个上下文
const UserContext = React.createContext()
export default UserContext
祖先组件:
import React, { Component } from 'react';
import Home from './Home';
import ThemContext from './context/them-context'
import UserContext from './context/user-context'
class classHello extends Component {
render() {
return (
<div>
<UserContext.Provider value={{nickName: 'zs'}}>
<ThemContext.Provider value={{color: 'red', size: '30'}}>
<Home />
</ThemContext.Provider>
</UserContext.Provider>
</div>
);
}
}
export default classHello;
父组件:
import React, { Component } from 'react'
import HomeInfo from './HomeInfo'
import HomeBanner from './HomeBanner'
export class Home extends Component {
render() {
return (
<div>
Home
<hr />
<HomeInfo />
<HomeBanner />
</div>
)
}
}
export default Home
孙组件:使用(获取context)
import React, { Component } from 'react'
import ThemContext from './context/them-context'
import UserContext from './context/user-context'
export class HomeInfo extends Component {
render() {
console.log(this.context);
return (
<div>
<p>HomeInfo(类组件):{this.context.color}</p>
<UserContext.Consumer>
{
value => {
return <h2>Info User:{value.nickName}</h2>
}
}
</UserContext.Consumer>
</div>
)
}
}
HomeInfo.contextType = ThemContext
export default HomeInfo
孙组件:使用(获取context)
import React from 'react'
import ThemContext from './context/them-context'
export default function HomeBanner() {
return (
<div>
HomeBanner(函数组件):
{
<ThemContext.Consumer>
{
value => {
return <span>{value.color}</span>
}
}
</ThemContext.Consumer>
}
</div>
)
}
现在的方式:
context/user-context.js
import {createContext} from 'react'
const UserContext = createContext()
export default UserContext
context/theme-context.js
import {createContext} from 'react'
const ThemeContext = createContext()
export default ThemeContext
context/index.js
import UserContext from "./user-context";
import ThemeContext from "./theme-context";
export {
UserContext,
ThemeContext
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { ThemeContext, UserContext } from './context';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<UserContext.Provider value={{name: 'zs',age: 20}}>
<ThemeContext.Provider value={{color:'red', size: 20}}>
<App />
</ThemeContext.Provider>
</UserContext.Provider>
);
reportWebVitals();
App.js:使用(获取context)
import React, { memo, useContext } from 'react'
import { ThemeContext, UserContext } from './context'
const App = memo(() => {
// useContext hook获取
const user = useContext(UserContext)
const theme = useContext(ThemeContext)
return (
<div>
<p>user: {user.name}--{user.age}</p>
<p>theme:{theme.color}--{theme.size}</p>
</div>
)
})
export default App
注意事项:
当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重新渲染,并使用最新传递给 MyContext provider 的 context value 值