iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0
自我挑戰組

菜雞們,讓我們一起征服JS及React吧系列 第 14

React菜雞-Day14:React Hook第4招 ~ useContext + useReducer 合體

  • 分享至 

  • xImage
  •  
tags: 鐵人賽 React javascript nodejs vscode

鐵人賽第14天,今天依舊工作滿檔,但該完成的任務還是要繼續,咱們立馬上工。

前言

  • 還記得我們前兩天教的useContextuseReducer吧!運用這兩者功能的特性,可以輕鬆地實現狀態及action global化,因此,不管要建立多深的component結構,都能輕鬆的存取狀態喔。

改寫昨天的範例,直接小露一手 /images/emoticon/emoticon77.gif

  • 我們複製昨天的範例並命名為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')
);

Demo

我的老天爺啊~這真的是太神奇了!! /images/emoticon/emoticon24.gif

  • 初始狀態

  • 按下A

  • 按下B

  • 按下C

結論 /images/emoticon/emoticon51.gif

  • 過去,要撰寫React必須要腦袋非常清晰的控制著component對應的狀態及函式。
  • 有了Context + useReducer這兩招的結合,簡直打通了我們的任督二脈,因此我們能:
  • 更有效透過檔案整理程式
  • 深層的component能存取到global state
  • 實現了中央控制的概念,隨心所欲的組織我們的component不再是難事,只能說~React你太神啦!

心得 /images/emoticon/emoticon62.gif

  • 鐵人賽第十四天,依舊是在通勤的火車上進行,今天下午因為工作,一度擔心完成不了,好在腦子一直在架構文章內容,才能順利的完成。
  • 菜雞已經蛻變一半了,還不給自己一個熱情的掌聲

上一篇
React菜雞-Day13:React Hook第3招 ~ useReducer讓你有降龍十八掌般的招式
下一篇
React菜雞-Day15:開發React程式的debug小幫手,讓你可以多睡幾小時的好工具
系列文
菜雞們,讓我們一起征服JS及React吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言