useEffect
是 React 中的一個非常重要的 Hook,用于處理組件的副作用(side effects)。它通常在以下幾種場景中使用:
1. 數據獲取
- 當組件加載時,需要從外部 API 獲取數據,或者從本地存儲中讀取數據。
- 示例:
useEffect(() => {fetch('https://api.example.com/data').then(response => response.json()).then(data => setData(data)); }, []); // 空依賴數組表示只在組件加載時執行一次
2. 訂閱和取消訂閱
- 當組件需要訂閱外部事件(如 WebSocket 消息、瀏覽器事件等)時,需要在組件加載時訂閱,在組件卸載時取消訂閱。
- 示例:
useEffect(() => {const handleResize = () => {console.log('Window resized');};window.addEventListener('resize', handleResize);// 返回一個清理函數return () => {window.removeEventListener('resize', handleResize);}; }, []); // 空依賴數組表示只在組件加載和卸載時執行
3. DOM 操作
- 當需要直接操作 DOM 元素時,
useEffect
是一個合適的地方。 - 示例:
useEffect(() => {const element = document.getElementById('myElement');element.style.color = 'red'; }, []); // 空依賴數組表示只在組件加載時執行一次
4. 設置全局狀態或外部狀態
- 當需要在組件加載時設置全局狀態(如 Redux 的 dispatch)或者外部狀態時。
- 示例:
useEffect(() => {dispatch(setUser(user)); }, [dispatch, user]); // 依賴數組包含 dispatch 和 user,當它們變化時重新執行
5. 清理資源
- 當組件需要清理某些資源(如定時器、訂閱等)時,
useEffect
的返回函數可以用來執行清理操作。 - 示例:
useEffect(() => {const timer = setTimeout(() => {console.log('Timer expired');}, 1000);// 清理定時器return () => clearTimeout(timer); }, []);
6. 響應狀態變化
- 當需要根據組件內部狀態的變化執行某些操作時,可以通過將狀態變量添加到依賴數組中來實現。
- 示例:
const [count, setCount] = useState(0);useEffect(() => {console.log(`Count changed to ${count}`); }, [count]); // 當 count 變化時重新執行
7. 模擬生命周期方法
- 在類組件中,
componentDidMount
、componentDidUpdate
和componentWillUnmount
的功能可以通過useEffect
來實現。 - 示例:
// componentDidMount useEffect(() => {console.log('Component mounted'); }, []);// componentDidUpdate useEffect(() => {console.log('Component updated'); });// componentWillUnmount useEffect(() => {return () => {console.log('Component will unmount');}; }, []);
8. 執行副作用操作
- 任何需要與外部世界交互的操作(如日志記錄、修改全局變量等)都可以放在
useEffect
中。 - 示例:
useEffect(() => {console.log('Logging component state'); });
使用 useEffect
的注意事項
- 依賴數組的正確性:
- 如果依賴數組為空(
[]
),useEffect
只會在組件加載時執行一次。 - 如果依賴數組中有變量,
useEffect
會在組件加載時以及依賴變量變化時重新執行。 - 如果依賴數組省略,
useEffect
會在每次組件渲染時都執行,這可能會導致性能問題。
- 如果依賴數組為空(
- 清理副作用:
- 如果
useEffect
中執行了需要清理的操作(如訂閱、定時器等),必須返回一個清理函數。
- 如果
- 避免無限循環:
- 如果
useEffect
中調用了導致狀態更新的函數,且依賴數組中包含該狀態變量,可能會導致無限循環。需要確保邏輯正確,避免這種情況。
- 如果
總之,useEffect
是一個非常強大的工具,可以幫助你在函數組件中處理各種副作用操作。