---
# System prepended metadata

title: React Hook useState、useEffect、useRef
tags: [React]

---

# React Hook useState、useEffect、useRef
###### tags: `React`
## :pushpin:useState
存儲狀態，並隨時更新
在應用程式中需要隨著時間改變的資訊，例如：使用者的輸入、點擊次數、當前選擇的選項等等。狀態必須在應用程式中被管理，並且隨著時間改變。
- 管理輸入框的內容：輸入文字時，管理輸入框的內容。
- 管理點擊次數：點擊按鈕時，管理點擊次數。
- 管理當前選擇的選項：多選框或單選框中選擇選項時，管理當前選擇的選項。
- 管理分頁：在分頁組件中翻頁時，管理當前頁數。
- 管理模型數據：載入從服務器端獲取的數據時，你可以使用 useState 管理這些數據。
```jsx=
const [count, setCount] = useState(0);
// setCount管理狀態方法 count存放狀態

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

```
## :pushpin:useEffect
在應用程式中的某些==指定的時間點==執行副作用（side effect）。例如：訂閱
* 監聽頁面滾動事件並執行特定操作
* 監聽組件大小變化並更新某些狀態
* 在組件卸載時清除某些事件監聽器
* 在狀態更新時設置或刪除本地存儲
* 在狀態更新時動態設置 CSS 屬性

```jsx=
const Example = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
};
```
## :pushpin:useRef
創建一個傳參考＆可儲存參考的物件，可以隨時存取和更新，不會受到重新渲染而改變。
:::info
- useState 管理元件中的狀態，刷新元件更新狀態
- useRef 管理元件中的參照，不會刷新整個元件 ex:`useRef.current`
:::
用途：
* 持續追踪某個值：持續追蹤某個值，即使它在狀態更新時被替換，也可以通過useRef的`.current`屬性訪問該值。
* 儲存非受控組件的值：在非受控組件中儲存值，例如==文本輸入的值==。
* 跨多個生命周期的數據共享：在組件的生命周期中共享數據，並在組件的不同生命周期中進行操作。
```jsx=
const inputRef = useRef(null);

return (
  <div>
    <input type="text" ref={inputRef} />
    <button onClick={() => inputRef.current.focus()}>
      Focus the input
    </button>
  </div>
);
```
![](https://i.imgur.com/9EudRPj.jpg)
## :pushpin:useContext
定義一個全局的狀態，然後在應用程式的任意位置訪問這個狀態。當元件在較深層時就不必透過傳props一層一層傳出去，使用CreatContext、useContext即可達到全域狀態
```jsx=
import React, { createContext, useContext, useState } from 'react';

// 建立一個主題顏色的全局狀態
const ThemeContext = createContext();

// 主題提供者，管理主題顏色狀態
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// 可以通過 useContext 存取主題狀態
function ThemeConsumer() {
  const { theme, setTheme } = useContext(ThemeContext);
  return (
    <>
      <p>當前主題顏色：{theme}</p>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        切换主題
      </button>
    </>
  );
}

function App() {
  return (
    <ThemeProvider>
      <ThemeConsumer />
    </ThemeProvider>
  );
}

export default App;

```
