Preact

返回 JavaScript框架

React 的轻量替代,API 与 React 完全兼容,压缩后仅 ~3KB(React ~45KB)。去掉了合成事件系统、PropTypes 等非核心部分,保留 Virtual DOM + Hooks 核心。


与 React 的关系

对比项ReactPreact
包体积(gzip)~45KB~3KB
API 兼容性通过 preact/compat 100% 兼容
事件系统合成事件(SyntheticEvent)原生 DOM 事件
渲染器react-dompreact 内置
Concurrent Mode支持不支持
Signals不内置@preact/signals(官方)

快速上手

npm create preact@latest
import { render } from "preact"
import { useState } from "preact/hooks"
 
function App() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
 
render(<App />, document.getElementById("app"))

Hooks 从 preact/hooks 导入,与 React 用法完全一致。


preact/compat 兼容层

将已有 React 项目迁移到 Preact,只需别名配置,无需改代码:

// vite.config.js
export default {
  resolve: {
    alias: {
      "react": "preact/compat",
      "react-dom": "preact/compat",
      "react/jsx-runtime": "preact/jsx-runtime",
    }
  }
}

Signals(响应式原语)

Preact 官方推出的细粒度响应式方案,比 useState 性能更高——仅更新实际用到该 signal 的 DOM 节点,不触发组件重渲染。

import { signal, computed } from "@preact/signals"
 
const count = signal(0)
const double = computed(() => count.value * 2)
 
function Counter() {
  return (
    <div>
      <p>count: {count}</p>
      <p>double: {double}</p>
      <button onClick={() => count.value++}>+1</button>
    </div>
  )
}

也可在 React 项目中通过 @preact/signals-react 使用。


服务端渲染(SSR)

import { render } from "preact-render-to-string"
import { App } from "./App.jsx"
 
const html = render(<App />)

Quartz 即用此方式将组件渲染为静态 HTML,组件无运行时水合。


Hooks 差异速查

// React
import { useState, useEffect, useRef } from "react"
 
// Preact(同名,不同包路径)
import { useState, useEffect, useRef } from "preact/hooks"

useMemouseCallbackuseContextuseReducer 用法与 React 完全相同。


适用场景

场景推荐
性能敏感的小型 Widget / Web Component✅ 首选
已有 React 项目降包体积preact/compat 无缝迁移
静态站点生成(SSG/SSR)✅ Quartz、Astro 均内置
需要 Concurrent Mode / Server Components❌ 用 React
深度依赖 Next.js 生态❌ 用 React

React(完整版)Vue