# 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; ```