框架

React

Hooks、常用模式与组件写法片段。 — 共 15 条

共 15 条代码片段

A. Hooks

useState 基本用法

const [count, setCount] = useState(0);

setCount(count + 1);
setCount((prev) => prev + 1);

useEffect 基本用法

useEffect(() => {
  // 挂载 / 依赖变化时执行
  const timer = setInterval(() => {}, 1000);
  return () => clearInterval(timer); // 清理
}, [deps]);

useRef 获取 DOM / 保存可变值

const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
  inputRef.current?.focus();
}, []);

return <input ref={inputRef} />;

useMemo 缓存计算结果

const filtered = useMemo(() => {
  return list.filter((item) => item.name.includes(keyword));
}, [list, keyword]);

useCallback 缓存回调

const handleClick = useCallback(() => {
  onSelect(id);
}, [id, onSelect]);

自定义 Hook:localStorage

function useLocalStorage<T>(key: string, initial: T) {
  const [value, setValue] = useState<T>(() => {
    if (typeof window === "undefined") return initial;
    try {
      const raw = localStorage.getItem(key);
      return raw ? (JSON.parse(raw) as T) : initial;
    } catch {
      return initial;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}

B. 常用模式

条件渲染

{loading && <Spinner />}
{error ? <ErrorMsg /> : <Content />}
{list.length ? <List items={list} /> : <Empty />}

列表渲染

{items.map((item) => (
  <li key={item.id}>{item.title}</li>
))}

forwardRef 转发 ref

const Input = forwardRef<HTMLInputElement, Props>(function Input(
  { label, ...rest },
  ref
) {
  return (
    <label>
      {label}
      <input ref={ref} {...rest} />
    </label>
  );
});

错误边界(类组件)

class ErrorBoundary extends React.Component<
  { children: React.ReactNode },
  { hasError: boolean }
> {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) return <h2>出错了</h2>;
    return this.props.children;
  }
}

Portal 弹层

import { createPortal } from "react-dom";

function Modal({ children }: { children: React.ReactNode }) {
  return createPortal(children, document.body);
}

C. Next.js

App Router metadata

export const metadata = {
  title: "页面标题",
  description: "页面描述",
};

动态路由 params

type Props = {
  params: Promise<{ slug: string }>;
};

export default async function Page({ params }: Props) {
  const { slug } = await params;
  return <div>{slug}</div>;
}

searchParams

type Props = {
  searchParams: Promise<{ q?: string }>;
};

export default async function Page({ searchParams }: Props) {
  const { q = "" } = await searchParams;
  return <div>关键词:{q}</div>;
}

客户端组件标记

"use client";

import { useState } from "react";

export default function Counter() {
  const [n, setN] = useState(0);
  return <button onClick={() => setN(n + 1)}>{n}</button>;
}