Excel定位条件全解析:从“空值”到“对象”,教你精准操控表格里的每一个元素
2026/6/10 21:16:52
React 19 带来了编译器、Actions、Form 原生支持、Server Components、新 Hooks等重大特性,开发规范相比 React 18 有颠覆性更新。
这份规范是企业级、可直接落地的标准,覆盖:项目结构、代码风格、组件编写、 Hooks 、表单/ Actions、性能、TypeScript、最佳实践。
<form action>+useActionState,弃用 Formik / React Hook Form(简单场景)use+ Suspense + Server Components,弃用冗余状态管理src/ ├── app/ # App Router 目录(Next.js / React 19 标准) │ ├── page.tsx # 页面入口(默认服务端组件) │ ├── layout.tsx # 根布局 │ ├── error.tsx # 错误边界 │ ├── loading.tsx # Suspense 加载 │ └── (routes)/ # 路由分组 ├── components/ # 公共组件 │ ├── ui/ # 基础 UI(Button、Input) │ ├── feature/ # 业务组件 │ └── client/ # 明确标记客户端组件 ├── lib/ # 工具函数、工具类 ├── actions/ # React 19 Server Actions ├── hooks/ // 自定义 Hooks ├── types/ # TS 类型定义 └── styles/ # 全局样式UserProfile.tsxUserProfile.tsxhandleSubmitMAX_RETRY_COUNTaction结尾submitFormActionuse开头useUserInfo<Input />// app/page.tsx 默认服务端组件 import { getUserList } from '@/actions/userActions' export default async function HomePage() { const users = await getUserList() // 直接 await 获取数据 return <div>{users.map(user => <p key={user.id}>{user.name}</p>)}</div> }// components/client/LikeButton.tsx 'use client' // 强制第一行 import { useState } from 'react' export default function LikeButton() { const [like, setLike] = useState(false) return <button onClick={() => setLike(!like)}>{like ? '已赞' : '点赞'}</button> }type UserCardProps = { user: { id: string; name: string } onDelete?: (id: string) => void } export default function UserCard({ user, onDelete }: UserCardProps) { return ( <div className="card"> <h3>{user.name}</h3> {onDelete && <button onClick={() => onDelete(user.id)}>删除</button>} </div> ) }因为每次数据状态改变刷新页面,都会执行组件函数。
useActionState:表单状态useFormStatus:表单提交状态useOptimistic:乐观更新use:读取 Promise / 上下文useState+useEffect获取数据use开头// hooks/useUserInfo.ts 'use client' import { use } from 'react' import { fetchUser } from '@/actions/userActions' export function useUserInfo(userId: string) { const user = use(fetchUser(userId)) // React 19 use() return { user } }React 19原生支持表单,彻底告别第三方库。
// actions/userActions.ts 'use server' // 服务端 Action export async function updateUserAction(prevState: any, formData: FormData) { const name = formData.get('name') // 数据库操作 return { success: true, message: '保存成功' } }'use client' import { useActionState } from 'react' import { updateUserAction } from '@/actions/userActions' export default function UserForm() { // React 19 表单状态 const [state, formAction] = useActionState(updateUserAction, null) const { pending } = useFormStatus() // 提交状态 return ( <form action={formAction}> <input name="name" defaultValue="张三" /> <button disabled={pending} type="submit"> {pending ? '保存中...' : '保存'} </button> {state?.message && <p>{state.message}</p>} </form> ) }const [optimisticUsers, addOptimisticUser] = useOptimistic( users, (state, newUser) => [...state, newUser] )useEffect获取数据loading.tsx/error.tsx// 客户端数据获取 'use client' import { use, Suspense } from 'react' function UserData({ userId }: { userId: string }) { const user = use(fetchUser(userId)) return <div>{user.name}</div> } export default function UserPage() { return ( <Suspense fallback={<div>加载中...</div>}> <UserData userId="1" /> </Suspense> ) }memo/useMemo/useCallbackkey,且不使用 index// 正确 key users.map(user => <User key={user.id} user={user} />) // 错误 key(禁止) users.map((user, idx) => <User key={idx} user={user} />)any,必须用unknown+ 类型守卫formDatatype User = { id: string name: string age?: number // 可选 } type ActionState = { success: boolean message?: string } export async function updateUserAction( prevState: ActionState, formData: FormData ): Promise<ActionState> { return { success: true } }'use client'、Hooks、事件useEffect充当数据请求action而用旧onSubmit示例:
feat: add user list server component