
Hook 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能。 (from 官方文件)
並「函式」來複用邏輯的概念,重新設計元件,更新粒度更細,讓程式碼更清晰, 並逐步將 class component 替換成函式型元件 Function Component。,簡單來說就是沒有template的組件,方便用於狀態及邏輯覆用。
呼叫同個方法,給同樣的參數,永遠應該返回同樣的值,react 元件中,給相同的 props ,渲染的 ui應該永遠一樣,但副作用和純函數相反,還處理了和返回值無關的事。簡單來說副作用,會去觀測監測值的變化,來做指定的事。
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `點擊${count}`;
  }, [count]);
P.S. useEffect 若不帶第二個參數,每次被渲染就會被調用,會造成無窮無死循環,若不想發生可以給他空 array。
P.S. useEffect watch 空 array 時,他只會初始化一次,在 Next JS 時可以當來用戶端初始化事件。

// 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();
 }, []);
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>}
<component test="" /> add perpery props interface React.FC<props>
P.S. Prop Drilling 簡而言之是指:當一個元件自身不需要這個prop,但為了使子元件能獲取到這個prop,而不得已去傳遞這個prop的行為。
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>
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 這種狀態管理的機制進行管理