iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Modern Web

關於React,那些我不知道的系列 第 28

不用Recoil的話,如何自己製作一個 Custom hook 來共享全域變數?(2)

  • 分享至 

  • xImage
  •  

實作自己的全域 count, setCount

codesandbox demo

  const { count, setCount } = useCountState();

1. 建立 Context

如同 Recoil 當中的 atom,或是可以參考更早之前介紹的文章 「 實現跨元件資料共享, useContext 」,我們需要的值有:

  • count
  • setCount
export const CountContext = createContext({
  count: 0,
  setCount: null
}); 

2. 建立實際 default value 跟 Provider

實際做出 count 這個 global state 跟 他的 setter function ,並提供給 Context Provider

export const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);
  const defaultValue = {
    count,
    setCount
  };
  return (
    <CountContext.Provider value={defaultValue}>
      {children}
    </CountContext.Provider>
  );
};

3. 在 App 或 index.js 放入 Provider 供整個專案使用。

export default function App() {
  return (
    <div className="App">
      <CountProvider>
        <h1>Hello CodeSandbox</h1>
        <Comp1 />
        <Comp2 />
      </CountProvider>
    </div>
  );
}

4. Custom Hook : 把 useContext 變成我們喜歡的模樣。

還記得在 「 實現跨元件資料共享, useContext 」 介紹時,我們認識了 useContext 這個 API ,
我們會在需要使用共享變數的地方,呼叫這個 hook , 並且明確帶入我們想要獲得的狀態 像是 const { theme } = useContext(ThemeContext) const { count, setCount } = useContext(CountContext) 。 此時在需要使用到這份 state 的檔案當中,就必須要明確引入 CountContext 、 ThemeContext 。

import React, { useContext } from "react";
import { CountContext } from "../somewhere/"
import { ThemeContext } from "./ThemeProvider";
const Comp1 = () =>{ 
  const { theme } = useContext(ThemeContext);
  const { count, setCount } = useContext(CountContext);
  return (
    <div style={{ backgroundColor: theme.background }}>
      <h2>count in Comp1 :{count} </h2>
      <button onClick={() => setCount(count + 1)}>increment</button>
    </div>
}

但有了 Custom hook 之後...,我們就可以如此縮寫。

export const useCountState = () => useContext(CountContext);

使我們可以把這個 context 封裝起來,不需要在其他元件內不斷 import 入,許多 context 如: CountContext 、 ThemeContext 。

import React from "react";
import { useCountState } from "./CountProvider";

const Comp1 = () => {
  const { count, setCount } = useCountState();
  return (
    <div>
      <h2>count in Comp1 :{count} </h2>
      <button onClick={() => setCount(count + 1)}>increment</button>
    </div>
  );
};

codesandbox demo


上一篇
不用Recoil的話,如何自己製作一個 Custom hook 來共享全域變數?
下一篇
styled-components 的初步探索
系列文
關於React,那些我不知道的30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言