鐵人賽
React
javascript
nodejs
vscode
鐵人賽第14天,今天依舊工作滿檔,但該完成的任務還是要繼續,咱們立馬上工。
useContext
及useReducer
吧!運用這兩者功能的特性,可以輕鬆地實現狀態及action global化,因此,不管要建立多深的component
結構,都能輕鬆的存取狀態喔。我們複製昨天的範例並命名為ReducerExample2
新增相關檔案,檔案結構如下
將ShowDiffText.js
中的3個buttons
移到 Buttons.js
import React, {useContext} from 'react';
import {contextStore} from "./ShowDiffText";
export default function Buttons() {
const {reducer} = useContext(contextStore);
const state = reducer[0];
const dispatch = reducer[1];
return (
<>
<div>
<button onClick={() => dispatch({type:"A"})}>A</button>
<button onClick={() => dispatch({type:"B"})}>B</button>
<button onClick={() => dispatch({type:"C"})}>C</button>
</div>
</>
);
}
ShowDiffText.js
中的reducer func
複製到reducers.js
// 建立reducer func
export default function myReducer(state, action) {
switch (action.type) {
case "A":
return "Hello A";
case "B":
return "Hello B";
case "C":
return "Hello C";
default:
return state;
}
}
ShowDiffText.js
- 注意到
第5行了
嗎?我們這次沒有使用const [state, dispatch] = useReducer(reducerFunc, initState)
的方式來接,而是直接接收一個Array
。- 所以要取出
state
,你可以透過第9行aReducer[0]
取出。- 同理
dispatch
就是aReducer[1]
囉!
import React, { useReducer, createContext } from "react";
import Buttons from "./Buttons";
import myReducer from "./Reducers";
export const contextStore = createContext();
export default function ShowDiffText() {
const aReducer = useReducer(myReducer, "Context + Reducer Demo"); //宣告 useReducer
const state = aReducer[0];
return (
<contextStore.Provider value={{reducer:aReducer}}>
<h2 style={{color:"blue"}}>{state}</h2>
<Buttons/>
</contextStore.Provider>
);
}
index.js
,存檔並啟動npm start
import React from 'react';
import ReactDOM from 'react-dom';
import ShowDiffText from "./components/ReducerExample2/ShowDiffText"; //<--只要改這行的路徑
ReactDOM.render(
<ShowDiffText/>,
document.getElementById('root')
);
我的老天爺啊~這真的是太神奇了!!
初始狀態
按下A
按下B
按下C
React
必須要腦袋非常清晰的控制著component
對應的狀態及函式。Context + useReducer
這兩招的結合,簡直打通了我們的任督二脈,因此我們能:
- 更有效透過檔案整理程式
- 深層的component能存取到global state