React / 已完成

React 入门篇:组件 JSX Props State

用 React 19、TypeScript、组件、JSX、Props 和 State 写用户管理页的第一版。

返回文章积累

一句话:React 入门先抓住一件事,页面是由组件拼出来的,组件根据 props 和 state 渲染界面。

第 2 篇 / 共 12 篇。

本篇学完你会:用 React 19 + TypeScript 写出用户管理页面的静态列表、拆组件、传 props、使用 state 控制选中和搜索输入。

1. React 是什么

React 是一个用 JavaScript/TypeScript 写用户界面的库。你可以把它想成“积木说明书”:每个组件是一块积木,整个页面就是积木组合。

React 最重要的公式是:

UI = Component(props, state)

意思是:组件拿到外部传入的 props 和自己内部的 state,然后返回界面。

React 组件 props state 心智图

2. 用户管理案例的第一步

我们先做最小版本:

用户管理页
- 顶部标题
- 搜索框
- 用户列表
- 用户状态标签
- 选中用户提示

先定义用户类型:

type UserStatus = 'active' | 'disabled';

type User = {
  id: number;
  name: string;
  email: string;
  role: 'admin' | 'member';
  status: UserStatus;
};

准备假数据:

const users: User[] = [
  { id: 1, name: '小明', email: 'ming@example.com', role: 'admin', status: 'active' },
  { id: 2, name: '小红', email: 'hong@example.com', role: 'member', status: 'disabled' }
];

3. JSX 是什么

JSX 看起来像 HTML,但它其实是 JavaScript 里的界面表达式。

function PageTitle() {
  return <h1>用户管理</h1>;
}

大白话:JSX 就是“在 JS 里写页面结构”。

注意两个差异:

HTMLJSX
classclassName
onclickonClick

比如:

<button className="primary" onClick={() => console.log('新增用户')}>
  新增用户
</button>

4. 组件是什么

组件就是一个可以复用的 UI 函数。

function UserStatusBadge({ status }: { status: UserStatus }) {
  return <span>{status === 'active' ? '正常' : '停用'}</span>;
}

它的好处是:状态标签以后哪里都可以用,不用每个页面复制一遍。

用户列表也可以拆成组件。为了让点击某一行能通知父组件,先把 onSelect 也设计进去:

function UserRow({ user, onSelect }: { user: User; onSelect: (id: number) => void }) {
  return (
    <li>
      <strong>{user.name}</strong>
      <span>{user.email}</span>
      <UserStatusBadge status={user.status} />
      <button onClick={() => onSelect(user.id)}>选择</button>
    </li>
  );
}

5. Props 是什么

props 是父组件传给子组件的数据。

function UserList({ users, onSelect }: { users: User[]; onSelect: (id: number) => void }) {
  return (
    <ul>
      {users.map((user) => (
        <UserRow key={user.id} user={user} onSelect={onSelect} />
      ))}
    </ul>
  );
}

这里 UserList 接收 usersonSelect,再把每个 user 传给 UserRow。点击某一行时,UserRow 不自己决定选中谁,而是调用父组件传来的 onSelect

大白话:props 像快递包裹,父组件把数据递给子组件,子组件只负责使用。

6. State 是什么

state 是组件自己记住的数据。比如搜索框当前输入了什么、当前选中了哪个用户。

import { useState } from 'react';

function UserManagementPage() {
  const [keyword, setKeyword] = useState('');
  const [selectedId, setSelectedId] = useState<number | null>(null);

  const filteredUsers = users.filter((user) => user.name.includes(keyword));

  return (
    <section>
      <h1>用户管理</h1>
      <input value={keyword} onChange={(event) => setKeyword(event.target.value)} placeholder="搜索用户名" />
      <UserList users={filteredUsers} onSelect={setSelectedId} />
      <p>当前选中用户 ID:{selectedId ?? '未选择'}</p>
    </section>
  );
}

useState('') 的意思是:请 React 帮我记住一个字符串,初始值是空。

7. 列表渲染和条件渲染

列表用 map

{users.map((user) => (
  <UserRow key={user.id} user={user} />
))}

条件用三元表达式或 &&

{users.length === 0 ? <p>暂无用户</p> : <UserList users={users} />}

key 很重要,它告诉 React 每一行是谁。用户列表最适合用稳定的 user.id

8. 常见错误

错误原因修正
直接修改 stateReact 不知道你改了setState
map 没写 keyReact 难以追踪列表项用稳定 ID
props 里改父组件数据数据方向乱了让父组件传回调
JSX 写 classJSX 属性不同className

如果 state 是数组,不要直接改旧数组:

selectedIds.push(user.id);

应该这样:

setSelectedIds((ids) => [...ids, user.id]);

9. 下一步怎么学

本篇你已经学到:

概念大白话
JSX在 JS 里写页面结构
组件可复用的 UI 函数
Props父组件传给子组件的数据
State组件自己记住的数据
列表渲染用数组生成一组 UI
条件渲染根据数据决定显示什么

下一篇建议:大白话讲解——React 核心篇:Hooks 表单 请求 用户列表.md