1. useContext简介
用 createContext 创建上下文对象,传递全局变量,在底层任意一个子组件可使用 useContext 获取该上下文对象,同时获取里面定义的全局变量值,进行渲染。
解决问题:当组件嵌套层级过多时,传递属性不方便。
2. useContext代码示例
javascript
import React, { useContext } from "react"
// 创建上下文
const UserContext = React.createContext({ name: '' })
function App() {
return (
// 用上下文包裹父组件
<UserContext.Provider value={{ name: 'Augus' }}>
<div>
<p>欢迎学习React后台课程</p>
<Parent />
</div>
</UserContext.Provider>
)
}
function Parent() {
return (
<div>
<p>
<span>Parent</span>
</p>
<p>
<Child />
</p>
</div>
)
}
function Child() {
// 在子组件中进行消费
const { name } = useContext(UserContext)
return <span>Child:{name}</span>
}
export default App
3. useReducer简介
useReducer 实际上是 useState 的升级版,都是用来存储和更新 state,只是应用的场景不一样。
一般情况下,我们使用 useState 就足够项目需要了,不多当遇到以下场景时,使用useReducer 会更好些 。
-
状态逻辑复杂:当状态的更新逻辑比较复杂时,使用 useReducer 可以将这个逻辑封装在 reducer 函数中,使代码更加清晰易懂;
-
多组件共享状态:当多组件需要共享一个状态时,可以将这个状态放在父组件,然后通过 useReducer 将状态和更新函数传递给子组件,从而实现状态共享;
-
需要处理连续的多个状态更新:当需要连续处理多个状态更新时,使用 useReducer 可以帮助我们更好地管理状态的变化和更新;
4. useReducer代码示例
javascript
import { useReducer } from "react"
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</>
);
}
5. useReducer的高级用法
javascript
import React, { useContext,useReducer} from "react"
// 创建上下文
const UserContext = React.createContext({})
function App() {
const reducer = (state:string,action:{type:string,name:string})=>{
switch(action.type){
case 'update_name':
return action.name
default :
return state
}
}
const [name,dispatch] = useReducer(reducer,'Augus');
return (
// 用上下文包裹父组件
<UserContext.Provider value={{ name,dispatch }}>
<div>
<p>欢迎学习React后台课程</p>
<Child1 />
<Child2 />
</div>
</UserContext.Provider>
)
}
function Child1(){
const { dispatch }:any = useContext(UserContext);
const handlick = ()=>{
dispatch({
type:'update_name',
name:Math.random()+''
})
}
return (
<p>
<span>Child1</span>
<button onClick={handlick}></button>
</p>
)
}
function Child2(){
const {name}:any = useContext(UserContext);
return (
<p>
<span>Child2:{name}</span>
</p>
)
}
export default App