不用Recoil的话,如何自己制作一个 Custom hook 来共享全域变数?(2)

实作自己的全域 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


<<:  Day28 语法改革!零基础新手也能读懂的JS - JS30-16 Mouse Move Shadow

>>:  Day 28 | 来组合个画面吧 - Part 1

Ruby、演算法学习心得(一) 二元搜寻法 Binary Search。

铁人赛结束後一阵空虚?? 文章内容都会以Ruby来撰写程序码,然後继续来传教K-POP啦! 有请韩国...

Golang 转生到web世界

Golang 因为对於web比较熟的关系,还是希望使用golang来做点web相关的事情,如果是写p...

苹果电脑密技:如何快速清除 Mac 快取/暂存档案?

当我们在 Mac 上打开和使用应用程序(如Google Chrome 浏览器等)或其他文件时,系统会...

延伸(1)-ML接入团队的原本开发生态 | ML#Day29

背景提要 团队走DevOps文化,所以频繁地沟通理解,以及任何东西考虑对於系统的定位,已经是我们再熟...

从 IT 技术面细说 Search Console 的 27 组数字 KPI (2) 流量 (1)

Search Console 中数百数千个数字中,若只拿一个数字给老版看的话,该看那一个,答案很简单...