Hello World - React 兼容的轻量应用

知识库
知识库文档
/tech-stacks/preact/examples/Hello World - React 兼容的轻量应用.md

文档

Preact Hello World — React 兼容的轻量应用

目标

展示 Preact 与 React 几乎相同的 API,同时强调其 3KB 的体量优势。包含 Hooks、组件和兼容模式示例。

完整代码

// src/main.jsx
import { render } from "preact";
import { App } from "./App";
import "./style.css";

render(<App />, document.getElementById("app"));
// src/App.jsx
import { useState, useEffect, useCallback, useMemo, useRef } from "preact/hooks";

export function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("朋友");
  const [theme, setTheme] = useState("light");
  const inputRef = useRef(null);

  // useEffect — 与 React 完全一致
  useEffect(() => {
    document.title = `Preact App - ${count} 次点击`;
  }, [count]);

  // useMemo — 自动优化
  const doubleCount = useMemo(() => count * 2, [count]);

  // useCallback — 缓存回调
  const focusInput = useCallback(() => {
    inputRef.current?.focus();
  }, []);

  return (
    <div className={`app ${theme}`}>
      <h1>⚛️ Preact Demo</h1>
      <p className="subtitle">
        仅 <strong>3KB</strong> 的 React 替代方案
      </p>

      {/* 双向绑定 */}
      <div className="input-group">
        <input
          ref={inputRef}
          value={name}
          onInput={(e) => setName(e.currentTarget.value)}
          placeholder="你的名字..."
        />
        <button onClick={focusInput}>聚焦输入框</button>
      </div>

      <p className="greeting">
        你好,<strong>{name}</strong>!
      </p>

      {/* 计数器 */}
      <div className="counter">
        <h2>{count}</h2>
        <p>2倍数:{doubleCount}</p>
        <div className="buttons">
          <button onClick={() => setCount((c) => c + 1)}>+1</button>
          <button onClick={() => setCount((c) => c - 1)}>-1</button>
          <button onClick={() => setCount(0)}>重置</button>
        </div>
      </div>

      {/* 主题切换 */}
      <button
        className="theme-toggle"
        onClick={() => setTheme((t) => (t === "light" ? "dark" : "light"))}
      >
        切换主题({theme})
      </button>

      {/* 条件渲染 */}
      {count >= 10 && (
        <div className="achievement">🏆 达到 10 次点击!</div>
      )}
    </div>
  );
}
/* src/style.css */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, 'Microsoft YaHei', sans-serif; }

.app {
  max-width: 480px; margin: 40px auto; padding: 0 16px;
  text-align: center; border-radius: 16px; padding: 32px;
  transition: background 0.3s, color 0.3s;
}

.app.light { background: #fff; color: #1a1a2e; }
.app.dark { background: #1a1a2e; color: #eee; }

.subtitle { color: #888; margin: 8px 0 24px; }

.input-group {
  display: flex; gap: 8px; margin-bottom: 16px;
}
.input-group input {
  flex: 1; padding: 10px; border: 2px solid #e2e8f0;
  border-radius: 8px; font-size: 1rem;
}
.input-group button {
  padding: 10px 16px; border: none; border-radius: 8px;
  background: #6366f1; color: white; cursor: pointer;
}

.counter h2 { font-size: 3rem; margin: 8px 0; }
.buttons button {
  padding: 10px 20px; border: none; border-radius: 8px;
  font-size: 1rem; cursor: pointer; margin: 4px;
  background: #10b981; color: white;
  transition: transform 0.15s;
}
.buttons button:hover { transform: translateY(-1px); }

.theme-toggle {
  margin-top: 20px; padding: 8px 20px;
  border: 1px solid #ccc; border-radius: 8px;
  background: transparent; cursor: pointer; font-size: 0.9rem;
}

.achievement {
  margin-top: 16px; padding: 12px;
  background: #fef3c7; border-radius: 8px; font-weight: 600;
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Preact App</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="./src/main.jsx" type="module"></script>
  </body>
</html>
// package.json(关键字段)
{
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "preact": "^10.19.0"
  },
  "devDependencies": {
    "@preact/preset-vite": "^2.7.0",
    "vite": "^5.0.0"
  }
}

运行步骤

npm install
npm run dev

预期输出

  • 界面与 React 几乎无法区分
  • 打包后 gzip 体积约 4KB(Preact 3KB + 组件代码)
  • 计数器、双向绑定、主题切换、条件渲染均正常工作

信息

路径
/tech-stacks/preact/examples/Hello World - React 兼容的轻量应用.md
更新时间
2026/5/31