溫馨提示:
使用react-hooks進行正常開發時,需要把組件和createContext創建上下文步驟單獨寫出來,哪里需要就在哪里引入
舉個實際的例子:子組件中修改父組件的 state
一般的做法是將父組件的方法比如 setXXX 通過 props 的方式傳給子組件,而一旦子組件多層級的話,就要層層透傳。
使用 Context 的方式則可以免去這種層層透傳
1、context-manager.js
創建一個上下文管理的組件,用來統一導出 Context 實例
import React from 'react'; export const MyContext = React.createContext(null);
2、父組件 Provider 提供上下文 value
下面代碼中,父組件引入了實例,並且通過 MyContext.Provider
將父組件包裝,並且通過 Provider.value
將方法提供出去。
下面的實例提供了三個 state 操作方法:
- setStep
- setCount
- setNumber
以及一個副作用方法:
- fetchData
子組件 Child
接受的 props 只有三個 state 的值 step/number/count
。
import React, { useState } from 'react'; import Child from './Child'; import { MyContext } from './context-manager'; const fetchData = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }) }); } export default (props = {}) => { const [step, setStep] = useState(0); const [count, setCount] = useState(0); const [number, setNumber] = useState(0); return ( <MyContext.Provider value={{ setStep, setCount, setNumber, fetchData }}> <Child step={step} number={number} count={count} /> </MyContext.Provider> ); }
3、子組件 useContext 解析上下文
下面是子組件,相同的,也需要從 context-manager
中引入 MyContext 這個實例,然后才能通過 const { setStep, setNumber, setCount, fetchData } = useContext(MyContext);
解析出上下文中的方法,在子組件中則可以直接使用這些方法,修改父組件的 state。
import React, { useContext, useEffect, memo } from 'react'; import { MyContext } from './context-manager'; export default memo((props = {}) => { const { setStep, setNumber, setCount, fetchData } = useContext(MyContext); useEffect(() => { fetchData().then((res) => { console.log(`FETCH DATA: ${res}`); }) }, []); return ( <div> <p>step is : {props.step}</p> <p>number is : {props.number}</p> <p>count is : {props.count}</p> <hr /> <div> <button onClick={() => { setStep(props.step + 1) }}>step ++</button> <button onClick={() => { setNumber(props.number + 1) }}>number ++</button> <button onClick={() => { setCount(props.step + props.number) }}>number + step</button> </div> </div> ); });
4、效果:
可以發現,在子組件中點擊按鈕,直接調用 Context 透傳過來的方法,可以修改父組件的 state,子組件則會重新渲染。
這種方式顯式的避免了多級 props 的層層透傳問題,雖然 Demo 只有一級 子組件,即使存在多級子組件也可以直接修改
.