React 基础用法:组件、JSX 与状态入门
React 基础用法:组件、JSX 与状态入门
React 用于以组件为单位搭建用户界面,核心是 声明式 UI:根据「当前状态」描述界面应长成什么样,状态变化后由 React 协调更新 DOM。下面从工程入口、JSX、属性与事件、列表与条件渲染,到函数组件里的 useState,做一条可跟练的基础线(与仓库内《React Hooks 入门》相衔接,本文偏「第一次写 React」)。
1. 创建工程与入口(概念)
常见脚手架:Vite(npm create vite@latest,模板选 React)、或 Create React App(维护节奏较慢,新项目更推荐 Vite)。安装依赖后,入口一般是 main.jsx 里用 createRoot 把根组件挂到页面节点上:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.jsx";
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>,
);
StrictMode在开发环境下会多做一次渲染等检查,帮助发现问题;生产构建中不影响行为。- 根节点通常是一个
index.html里的<div id="root"></div>。
2. JSX:在 JavaScript 里写标签
JSX 是 JavaScript 的语法扩展,看起来像 HTML,实际会被编译成 React.createElement 调用。规则要点:
- 只能返回一个根节点(若不想多包一层
div,可用 Fragment:<>...</>或<Fragment>...</Fragment>)。 - 用
className代替 HTML 的class;style传入对象,例如style={{ marginTop: 8 }}(驼峰 CSS 属性名)。 - 在标签内用
{表达式}插入变量或运算结果;{true && <span />}常用于条件片段。
function Welcome({ name }) {
const title = `你好,${name}`;
return (
<section className="welcome">
<h1>{title}</h1>
</section>
);
}
3. 函数组件与 props
组件即函数,首字母大写;props 是只读的入参,用于父组件向子组件传数据。常用写法是解构:
function Avatar({ src, alt }) {
return <img src={src} alt={alt} width={48} height={48} />;
}
export function UserCard({ name, avatarUrl }) {
return (
<article>
<Avatar src={avatarUrl} alt={name} />
<p>{name}</p>
</article>
);
}
- 不要在子组件里改写
props对象本身;需要「可编辑副本」时在子组件内部用 state 或派生值。 - 子组件未使用的 props 可忽略;需要默认值时可用默认参数:
function Box({ title = "无标题" }) { ... }。
4. 事件与表单
React 里事件名采用驼峰,如 onClick、onChange,传入函数引用或内联函数:
function Button() {
const handleClick = () => {
console.log("clicked");
};
return (
<button type="button" onClick={handleClick}>
点我
</button>
);
}
- 表单输入框要变成「受控组件」,通常把
value与onChange与 state 绑定在一起(见下一节)。 type="button"可避免在表单里误触提交;真正提交用type="submit"并在onSubmit里event.preventDefault()。
5. 状态:useState(函数组件)
状态变化会触发组件重新渲染。在函数组件中用 useState 声明状态:
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button type="button" onClick={() => setCount((c) => c + 1)}>
计数:{count}
</button>
);
}
- 不要直接修改
count本身(例如count++),应调用setCount;对象/数组更新需拷贝后再设新引用。 - 若新状态依赖旧状态,推荐
setCount((c) => c + 1)这种函数形式,避免闭包读到旧值。 - 更多 Hooks(
useEffect、useMemo等)可在同仓库文章《React Hooks 入门》中延伸。
6. 列表与 key
用 map 渲染列表时,每个兄弟元素应有稳定的 key(通常用数据 id,不要用数组下标充当唯一标识——除非列表静态且永不重排)。
function TodoList({ items }) {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
key 只用于协调算法,不会传给 DOM;若子组件需要 id,请单独用 props 传递。
7. 条件渲染
常用模式:condition ? <A /> : <B />、condition && <A />,或先算好变量再 return。
function Banner({ error }) {
if (error) {
return <p role="alert">{error}</p>;
}
return <p>一切正常</p>;
}
8. 小结与注意点
| 主题 | 建议 |
|---|---|
| 组件 | 优先写函数组件;逻辑复用交给 Hooks 或拆小组件。 |
| props | 当作只读;默认值用参数默认值或显式判断。 |
| 状态 | 谁使用谁持有;避免为「可计算」的值单独建 state。 |
| 性能 | 入门阶段不必过早优化;列表务必有稳定 key。 |
| 版本 | 新教程默认基于 React 18;API 以 react.dev 为准。 |
把上述片段放进 Vite 创建的 React 项目里改一改、跑一跑,再读 React Hooks 入门,即可较平滑地进入日常开发。
