返回
Featured image of post React - Hook

React - Hook

React - Hook,不必寫 class 就能使用 state 以及其他 React 的功能

歷史回顧一下:
在我學習 Vue2.0 的過程中,其實控制一款全局狀態的東西叫做 Vuex 在我的印象認知來說 React也有一款控制全局狀態的套件 Redux
ReduxVuex 都是從 Flux 這套衍伸出來的概念,優質文章:Vuex与Redux比较
React Hook 又是什麼樣的狀態呢?讓我蠻期待的!,之後也會補一下 Redux 的相關使用。


Hook 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能

Hook 不會取代你對 React 概念的了解。
相反的,Hook 是對你已經熟悉的 React 概念:props、state、context、refs 以及 lifecycle,提供了一個更直接的 API。正如我們稍後將展示的那樣,Hook 還提供了一種新的強大方式來組合他們。

Hook 的規則

別在一般的 JavaScript function 中呼叫 Hook。相反的,你可以:

  • ✅ 在 React function component 中呼叫 Hook。
  • ✅ 在自定義的 Hook 中呼叫 Hook。(我們將會在下一頁了解它們)。
    透過遵循這些規則,你確保了在 component 中所有的 stateful 邏輯在其原始碼中可以清楚地被看見。

📌 State Hook

import React, { useState } from 'react';

function Example() {
  // 宣告一個新的 state 變數,我們叫他「count」
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

使用多個 State 變數

把 state 變數宣告成一對 [something, setSomething] 同時也很便利,因為如果想要使用超過一個 state 變數,這能讓我們對不同的 state 變數有不同的命名

  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);

⚡️ Effect Hook

如果你熟悉 React class 的生命週期方法,你可以把 useEffect 視為 componentDidMountcomponentDidUpdatecomponentWillUnmount 的組合。
超強大的功能啊,融合生命週期的強大功能,如果夠熟悉生命週期,API呼叫就完全就直接上Hook,(限制在 function React)

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  // 重點還可以多個 Effect !!! 超強大的功能
  useEffect(() => {
    document.title = `Hello World!`;
  });

  useEffect(() => {
    // 執行的開始 對應生命週期來說 = componentDidMount(){ ... }
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    // 執行的更新 對應生命週期來說 = componentDidUpdate(){ ... }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // 執行的最後 對應生命週期來說 =  componentWillUnmount(){ ... }
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

當某個 State 狀態更新呼叫參數

  useEffect(() => {
    const id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id);
  }, [count]); // 畫面進到 mount 全部都會執行一次,然後在 [] 中 的變數當進行更動時也會執行此 useEffect() Function 

💡 打造你自己的 Hook

通常 component 遇到相同的邏輯,就可以把這個固定 Function 拉到共用層級
以 ExpressJS 資料夾層級,可以當作 middlewareutils 層級

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // 處理friendID邏輯處理,去判斷 isOnline

  return isOnline;
}

function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id); // 引用 useFriendStatus()

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

優質文章


讀後心得

2018 年底的 react16.8,現在已經 2021 年,這樣也已經將近三年的時間後我才有機會碰到 React, 之前學習的 Vue 也卡在 2.x 的時期,如今 Vue 也進化到 3.x 版本,看來要繼續把該補的知識補一點起來。

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus