溫馨提示:
使用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 只有一級 子組件,即使存在多級子組件也可以直接修改
.
