Mark Ku's Blog
首頁 關於我
React 學習筆記 - 何謂 React Hook、副作用、Loading、錯誤處理、上下文關係(Context) - Part's 4
Frontend
React 學習筆記 - 何謂 React Hook、副作用、Loading、錯誤處理、上下文關係(Context) - Part's 4
Mark Ku
Mark Ku
July 23, 2022
1 min

何謂 React Hook

Hook 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能。 (from 官方文件)
並「函式」來複用邏輯的概念,重新設計元件,更新粒度更細,讓程式碼更清晰, 並逐步將 class component 替換成函式型元件 Function Component。,簡單來說就是沒有template的組件,方便用於狀態及邏輯覆用。

何副作用 Effect

呼叫同個方法,給同樣的參數,永遠應該返回同樣的值,react 元件中,給相同的 props ,渲染的 ui應該永遠一樣,但副作用和純函數相反,還處理了和返回值無關的事。簡單來說副作用,會去觀測監測值的變化,來做指定的事。

useEffect 異步存取資料

  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `點擊${count}`;
  }, [count]);

P.S. useEffect 若不帶第二個參數,每次被渲染就會被調用,會造成無窮無死循環,若不想發生可以給他空 array。
P.S. useEffect watch 空 array 時,他只會初始化一次,在 Next JS 時可以當來用戶端初始化事件。

因為 useEffect 是同步方法,但可以用直接 promise,如果要用 async wait,則必在 useEffect 裡擴充一個 async 方法,並執行他

// promise 用法
const responses = fetch(
     "https://jsonplaceholder.typicode.com/users"
   )
   .then(response => response.json())
   .then(data => setRobotGallery(data))

// async await 用法
 useEffect(() => {
   const fetchData = async () => {
     const res = await fetch("https://jsonplaceholder.typicode.com/users");      

     const data = await res.json();
     setRobotGallery(data);
   };

   fetchData();
 }, []);

Loading

const [loading, setLoading] = useState<boolean>(false);
{!loading ? (
        <div className={styles.robotList}>
          {robotGallery.map((r) => (
            <Robot key={r.id} id={r.id} email={r.email} name={r.name} />
          ))}
        </div>
      ) : (
        <h2>loading</h2>
)}

錯誤處理

 const [error, setError] = useState<string>();

 try {
       throw new Error("網站錯誤")               
} catch (e) {
 if (e instanceof Error) {
    setError(e.message);
    }
}      
    
{(!error || error !== "") && <div>{error}</div>}

上下級元件參數傳遞

一般來說可以透過 props 傳遞參數到子元件,但自身不需要这个prop,但为了使子组件能获取到这个prop,則會衍生 Prop Drilling 的問題。

<component test="" />
add perpery props interface 
React.FC<props>

P.S. Prop Drilling 簡而言之是指:當一個元件自身不需要這個prop,但為了使子元件能獲取到這個prop,而不得已去傳遞這個prop的行為。

這時就可以用 React 上下文關係 context

const defaultContextValue = {
  username: "阿來克斯",
};

export const appContext = React.createContext(defaultContextValue);

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <appContext.Provider value={defaultContextValue}>
      <App />
    </appContext.Provider>
  </React.StrictMode>
);

使用的元件

import { appContext } from "../index";
<appContext.Consumer>
      {(value) => {
        return (
          <div className={styles.cardContainer}>            
            <p>{value.username}</p>
          </div>
        );
      }}
</appContext.Consumer>

useContext Hook 簡化寫法,可以不用層層套崁

onst Robot: React.FC<RobotProps> = ({ id, name, email }) => {
const value = useContext(appContext)

  return (        
          <div className={styles.cardContainer}>
            <img alt="robot" src={`https://robohash.org/${id}`} />
            <h2>{name}</h2>
            <p>{email}</p>
            <p>{value.username}</p>
          </div>            
  );
};

P.S. 那麼如果,組件若不是上下級關係時,又不想一層層傳進去,則需要考慮用 redux 這種狀態管理的機制進行管理


Tags

Mark Ku

Mark Ku

Software Developer

9年以上豐富網站開發經驗,開發過各種網站,電子商務、平台網站、直播系統、POS系統、SEO 優化、金流串接、AI 串接,Infra 出身,帶過幾次團隊,也加入過大團隊一起開發。

Expertise

前端(React)
後端(C#)
網路管理
DevOps
溝通
領導

Social Media

facebook github website

Related Posts

這些年對 Next.JS 做過的網站效能優化
這些年對 Next.JS 做過的網站效能優化
October 10, 2024
1 min

Quick Links

關於我

Social Media