useContext
1. 说明
useContext
,能够让我们在函数组件中使用context的能力, 替换之前的 context.Consumer
2. 语法
2.1 语法格式
const value = useContext(MyContext);
2.2 语法说明
- 参数 : 一个 context对象
- 返回值 : 返回 Provider 提供的 value 值
2.3 使用说明
- 回忆 :
- 之前在类组件件中 , 使用 context实现从上到下跨多层组件传递数据
1. 通过 createContext() 创建 context对象
const myContext = React.createContext()
2. 在context对象中,提供了一个自带的 Provider 组件, 用来提供数据。
<myContext.Provider value={ 数据 }>
....
</myContext.Provider>
3. 在context对象中,提供了一个自带的 Consumer 组件, 用来接收数据。
<myContext.Consumer>
{ data => data 就是传递过来的数据 }
</myContext.Consumer>
- 在函数组件中, 使用 useContext hook 可以实现三个功能
- 功能1 : 实现从上到下跨多层组件传递数据
- 功能2 : 兄弟组件数据交互 (共享数据)
- 功能3 : 配合 useReducer 组合 redux
3. 使用
3.1 功能1-跨多层组件传递数据
import React from 'react'
export default React.createContext()
import myContext from './demo1/context'
<myContext.Provider value={'哈哈哈'}>
...
<Child></Child>
</myContext.Provider>
import myContext from './context'
const Child = () => {
const val = useContext(myContext)
return <div>子组件 - { val }</div>
}
3.2 功能2-封装 Provider-共享数据
import React, { useState } from 'react'
export const myContext = React.createContext() # 导出 myContext
export function MyProvider({ children }) { # 导出 函数组件
const [count, setCount] = useState(0)
const value = {
count,
increment: () => setCount(count + 1),
decrement: () => setCount(count - 1)
}
return <myContext.Provider value={value}>{children}</myContext.Provider>
}
import React, { useContext } from 'react'
import { myContext } from './context' # 引入 myContext
const Counter1 = () => {
const { counter, increment, decrement } = useContext(myContext) # 获取共享数据
return (
<div>
<div>函数组件1 - {counter}</div>
<button onClick={() => increment()}>函数组件 +1</button>
<button onClick={() => decrement()}>函数组件 -1</button>
</div>
)
}
export default Counter1
import React, { useContext } from 'react'
import { myContext } from './context' # 引入 myContext
const Counter2 = () => {
const { counter, increment, decrement } = useContext(myContext) # 获取共享数据
return (
<div>
<div>函数组件2 - {counter}</div>
<button onClick={() => increment()}>函数组件 +1</button>
<button onClick={() => decrement()}>函数组件 -1</button>
</div>
)
}
export default Counter2
import React from 'react'
import Counter1 from './demo2/Counter1'
import Counter2 from './demo2/Counter2'
import { MyProvider } from './context' # 引入 MyProvider
const App = () => {
return (
<div>
# 包裹着要共享数据的组件
<MyProvider>
<Child1></Child1>
<Child2></Child2>
</MyProvider>
</div>
)
}
export default App
3.3 功能3- useContext 和 useReducer 组合 redux
import React from 'react'
import { useReducer } from 'react'
export const myContext = React.createContext()
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return state + 1
case 'decrement':
return state - 1
default:
return state
}
}
export const MyProvider = ({ children }) => {
const [count, dispatch] = useReducer(reducer, 0)
const values = {
count,
dispatch
}
return <myContext.Provider value={values}>{children}</myContext.Provider>
}
import React from 'react'
import Counter1 from './Counter1'
import Counter2 from './Counter2'
import { MyProvider } from './context'
const App = () => {
return (
<div>
<div>函数组件</div>
<MyProvider>
<Counter1></Counter1>
<Counter2></Counter2>
</MyProvider>
</div>
)
}
export default App
import React from 'react'
import { useContext } from 'react'
import { myContext } from './context'
const Counter1 = () => {
const { count, dispatch } = useContext(myContext)
return (
<div>
<div>Counter1 - {count}</div>
<button onClick={() => dispatch({ type: 'increment' })}>+1</button>
</div>
)
}
export default Counter1
import React from 'react'
import { useContext } from 'react'
import { myContext } from './context'
const Counter2 = () => {
const { count, dispatch } = useContext(myContext)
return (
<div>
<div>Counter2 - {count}</div>
<button onClick={() => dispatch({ type: 'decrement' })}>-1</button>
</div>
)
}
export default Counter2