1.useContext的作用:
Context是一种对其所包含组件树提供全局共享数据的技术,而useContext是在React Hooks中对Context进行的封装,他可以帮助我们跨越组件层级直接传递数据,实现数据共享,让使用变得更简单
假设我们在根组件嵌入子组件A,在子组件A嵌入孙组件B,我们想直接通过根组件向孙组件B传递参数,我们就可以使用useContext来实现
2.useContext的基础语法和参数说明:
const AppContext = React.createContext(initialValue);
const MyContext = useContext(AppContext);
initialValue参数是context的初始值,useContext的返回值有如下两种:
MyContext.Provider:提供者,是React组件,使用Provider标签包裹后的组件,自身及其后代组件都可以访问MyContext的值
MyContext.Consumer:消费者,是React组件,使用Consumer包裹后,可以使用render props(回调函数)的方式渲染内容,获取MyContext的值
对于<MyContext.Provider value={ [keyName]:'keyValue' } />需要注意此处属性名称必须为value,并且值为一个键值对对象,如:
<MyContext.Provider value={ userName:'xiaoming' }>
</MyContext.Provider>
3.例子:
import React, { useContext } from 'react';
const AppContext = React.createContext({} as any)
const C = () => {
const appContext = useContext(AppContext)
const handleChange = () => {
console.log(appContext)
}
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#ccc',
margin: '50px',
padding: '50px'
}}>
<div>子组件C</div>
<button type="button" onClick={handleChange}>change</button>
</div>
)
}
const B = () => {
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#999',
margin: '50px'
}}>
<div>子组件B</div>
<C></C>
</div>
)
}
const A = () => {
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#666',
margin: '50px'
}}>
<div>子组件A</div>
<B></B>
</div>
)
}
const App = () => {
return (
<div style={{
width: 'auto',
float: 'left',
border: '1px solid #000',
margin: '50px'
}}>
<div>通过根组件传参给子组件C</div>
<AppContext.Provider value={{
userName: "xiaoming",
userAge: 22,
userSex: true
}}>
<A></A>
</AppContext.Provider>
</div>
)
}
export default App
React支持并行使用多个useContext,示例如下:
import React, { useContext, useState } from 'react';
const AppContext = React.createContext({} as any)
const ThemeContext = React.createContext({} as any)
const C = () => {
const appContext = useContext(AppContext)
const themeContext = useContext(ThemeContext)
const handleChange = () => {
console.log(appContext.data)
console.log(themeContext.color)
}
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#ccc',
margin: '50px',
padding: '50px'
}}>
<div>子组件C</div>
<div>主题:{themeContext.color}</div>
<button type="button" onClick={handleChange}>change</button>
</div>
)
}
const B = () => {
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#999',
margin: '50px'
}}>
<div>子组件B</div>
<C></C>
</div>
)
}
const A = () => {
return (
<div style={{
width: 'auto',
float: 'left',
backgroundColor: '#666',
margin: '50px'
}}>
<div>子组件A</div>
<B></B>
</div>
)
}
const App = () => {
const [data, setData] = useState({
userName: "xiaoming",
userAge: 22,
userSex: true
})
const [theme, setTheme] = useState('red')
return (
<div style={{
width: 'auto',
float: 'left',
border: '1px solid #000',
margin: '50px'
}}>
<div>通过根组件传参给子组件C</div>
<AppContext.Provider value={{ data: data }}>
<ThemeContext.Provider value={{ color: theme }}>
<A></A>
</ThemeContext.Provider>
</AppContext.Provider>
</div>
)
}
export default App
例子2:
import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext({} as any)
// 通过useContext获取
const B = () => {
const getTheme = useContext(ThemeContext)
return (
<div>{getTheme.color}</div>
)
}
// 通过Consumer获取
const C = () => {
return (
<div>
<ThemeContext.Consumer>
{
x => <div>{x.color}</div>
}
</ThemeContext.Consumer>
</div>
)
}
const App = () => {
const [theme, setTheme] = useState('red')
const handleClick = () => {
setTheme('blue')
}
return (
<div>
<button onClick={handleClick}>change</button>
<ThemeContext.Provider value={{color:theme}}>
<B></B>
<C></C>
</ThemeContext.Provider>
</div>
)
}
export default App