在目前市場上的前端框架中,React 一直是最受歡迎的 JavaScript 框架之一,但隨著功能的開發及業務邏輯的增長,導致整個專案變得更加複雜,我們需要更多的工具和技術來管理狀態和副作用。這正是 React Hooks 出現的原因,它們為我們提供了一種更簡單、更可讀、更可維護的方式來處理組件內部的邏輯。本文將深入介紹 useState Hook 和 useEffect Hook,這兩個 Hook 是 React 中最常見的,它們分別用於處理狀態管理和副作用處理。我們將通過詳細的解釋和程式碼做範例,幫助您理解它們的用途和工作原理。
useState Hook:
useState Hook 是 React 提供的一種狀態管理工具,它允許我們在 Functional Component 中添加狀態。這消除了傳統的 Class Component 中的冗長代碼,使我們能夠更容易地跟蹤和更新 Component 的狀態。我們將深入研究 useState 的用法,包括如何定義初始狀態、訪問狀態值以及更新狀態。
useEffect Hook:
useEffect Hook 用於處理副作用,例如數據加載、訂閱、DOM 操作等。它讓我們能夠在 Component 渲染後執行程式碼,並在需要時清理資源,以確保應用程式的一致性和性能。我們將解釋如何使用 useEffect 來處理常見的副作用情境,並講解清理機制以避免潛在的問題。
範例一:以下是一個簡單的範例,展示了useState 和 useEffect Hook 的使用。我們將創建一個計數器 Component,用 useState 來管理計數器的狀態,並使用 useEffect 來設置一個計時器,每秒更新計數器的值。
import React, { useState, useEffect } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => {
clearInterval(timer); // 在組件卸載時清理計時器
};
}, []);
return (
<div>
<p>計數器值:{count}</p>
</div>
);
}
export default Counter;
範例二:這次我們將創建一個簡單的代辦事項列表,並使用 useState 來管理代辦事項的狀態,使用 useEffect 來模擬從後端獲取數據的操作。
import React, { useState, useEffect } from 'react';
const TodoList = () => {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
useEffect(() => {
// 模擬從後端獲取代辦事項列表的操作
const fetchData = async () => {
try {
// 假設這是一個API請求
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const data = await response.json();
setTodos(data.slice(0, 5)); // 只取前五個代辦事項
} catch (error) {
console.error('獲取代辦事項列表時出錯:', error);
}
};
fetchData();
}, []); // 空依賴陣列表示只在組件首次渲染時執行
const handleAddTodo = () => {
if (newTodo.trim() !== '') {
setTodos([...todos, { id: Date.now(), title: newTodo, completed: false }]);
setNewTodo('');
}
};
return (
<div>
<h2>代辦事項列表</h2>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.title} - {todo.completed ? '已完成' : '未完成'}
</li>
))}
</ul>
<div>
<input
type="text"
placeholder="新增代辦事項"
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
/>
<button onClick={handleAddTodo}>新增</button>
</div>
</div>
);
}
export default TodoList;