Preact Hooks 是 Preact 提供的一种功能强大的特性,它允许你在不使用 class 组件的情况下,复用状态逻辑。本章将详细介绍如何使用 Preact Hooks 来构建更加简洁、高效的组件。
简介
Hooks 是一种在函数组件中添加状态和生命周期行为的方法。通过使用 Hooks,我们可以避免使用类组件,从而简化代码结构,并且更容易理解组件的逻辑。
基础 Hooks
useState
useState 是一个基础的 Hook,用于在函数组件中添加状态。它接收一个参数作为初始状态,返回一个数组,其中第一个元素是当前状态,第二个元素是一个更新状态的函数。
// www.javascriptcn.com code example
import { h, render } from 'preact';
import { useState } from 'preact/hooks';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
</div>
);
}
render(<Counter />, document.body);useEffect
useEffect 用于处理副作用操作,例如数据获取、订阅或手动更改 DOM。它接收两个参数:一个执行副作用的函数和一个可选的依赖项数组。
// www.javascriptcn.com code example
import { h, render } from 'preact';
import { useEffect, useState } from 'preact/hooks';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setSeconds(seconds => seconds + 1);
}, 1000);
// 清理函数
return () => clearInterval(intervalId);
}, []);
return (
<div>
<p>Seconds: {seconds}</p>
</div>
);
}
render(<Timer />, document.body);useContext
useContext 用于读取 React Context。这使得组件能够访问到父组件传递下来的上下文值,而无需手动通过 props 逐层传递。
// www.javascriptcn.com code example
import { h, render } from 'preact';
import { createContext, useContext, useState } from 'preact/hooks';
const ThemeContext = createContext('light');
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>Toggle Theme</button>;
}
render(<App />, document.body);自定义 Hooks
自定义 Hooks 允许我们将组件中的逻辑提取出来,以便在多个组件之间重用。自定义 Hooks 必须以 use 开头,这样它们才能被正确地识别为 Hooks。
useFetch
useFetch 是一个自定义 Hook,用于从 API 获取数据。
// www.javascriptcn.com code example
import { useState, useEffect } from 'preact/hooks';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
setError(error.message);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
function UserList() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
render(<UserList />, document.body);总结
通过使用 Preact Hooks,我们能够编写更加简洁和高效的组件。基础 Hooks 如 useState 和 useEffect 提供了管理状态和副作用的能力,而自定义 Hooks 则让我们可以轻松地重用逻辑。希望本章的内容能帮助你更好地理解和应用 Preact Hooks。