React 快速上手
约 2348 字大约 8 分钟
React
2025-08-03
JSX
React 应用是由组件组成的,每个组件都拥有逻辑和视图。组件则是一个返回标签的函数。
把HTML写在JS中,这种写法叫做 JSX,它比HTML的语法更严格,比如必须闭合标签。
一个组件只能返回一个根元素,如果需要返回多个元素,可以将他们包裹在一个父元素中,比如<div>
,或者使用空的标签<>...</>
。
function MyComponent() {
return (
<>
<h1>Hello, World!</h1>
<p>This is my first React component.</p>
</>
);
}
样式
在 React 中,使用className
来在元素中添加 CSS 类名,而不是使用 HTML 中的 class
属性,但它的作用是一样的。
标记完类名后,就可以在单独的 CSS 文件中定义样式,或者使用内联样式。
function MyComponent() {
return <div className="my-class">Hello, World!</div>;
}
// 等同于
// <div class="my-class">Hello, World!</div>;
显示数据
JSX 让 HTML 写在 JS 中,在 HTML 中再通过大括号又可以回到JS中,即可嵌入数据。
return <h1>Hello, {user.name}!</h1>;
JSX 中的 HTML 属性也可以使用大括号来嵌入 JavaScript 表达式,其中可以写一些复杂的表达式,比如字符串拼接、函数调用等。
return <img src={user.avatarUrl} alt={'The avatar of ' + user.name} />;
style={{
width: user.imageSize,
height: user.imageSize
}}
上面的代码只是style
的一个属性,该属性是一个对象,并非类似Vue的插值语法。
比如
<h1 style={{ color: 'red', fontSize: '50px' }}>Hello World</h1>
将被渲染为:
<h1 style="color: red; font-size: 50px;">Hello World</h1>
原生CSS的属性通常是连字符分隔的,比如font-size
,而在JSX中则使用驼峰命名法,即fontSize
,background-color 则是 backgroundColor。
条件渲染
React 中的条件渲染靠的是 JavaScript 的条件语句,比如 if
、else
、三元运算符等。
let isShowing = true;
if(isShowing){
content = <Login/>
}
else {
content = <Logout/>
}
return <div>{content}</div>;
或者使用三元运算符:
return (
<div>
{isShowing ? <Login /> : <Logout />}
</div>
);
使用短路运算符也可以实现条件渲染,但是需要注意的是,如果条件为 false
,则不会渲染任何内容。
return (
<div>
{isShowing && <Login />}
</div>
);
渲染列表
仍然依赖于JS的数组方法,比如 map
。
const items = [
{
id: 1,
name: 'Item 1'
},
{
id: 2,
name: 'Item 2'
},
{
id: 3,
name: 'Item 3'
}
];
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
或者:
const result = items.map((item) => (
<li key={item.id}>{item.name}</li>
)
);
return <ul>{result}</ul>;
注意:其中有一个key
属性,它是 React 用来标识每个元素的唯一标识符,帮助 React 更高效地更新和渲染列表,兄弟元素之间的 key
必须唯一。
响应事件
可以在组件中声明事件处理函数,并将其绑定到元素的事件上。
function Component() {
function handleClick() {
console.log('Button clicked!');
}
return <button onClick={handleClick}>Click me</button>;
}
export default component;
注意:在JSX中,事件处理函数的的结尾没有加上括号,这并不是一个函数调用,而是一个函数引用,只需要将函数名传递给事件即可。
更新界面
如果要实现一个显示按钮的点击次数,需要定义组件的状态(变量),并在事件处理函数中更新状态。
通常使用useState
Hook 来定义状态,而不原生JavaScript 中的变量。
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 定义状态变量 count 和更新函数 setCount
function handleClick() {
setCount(count + 1); // 更新状态
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default Counter;
useState
函数返回一个数组,第一个值是状态变量,第二个值是更新状态的函数,你可以自定义变量名,但通常推荐使用 ??
来表示状态变量,set??
来表示更新函数。
状态的变量的初始值就是useState
函数的参数。
你可以复用组件,每次点击按钮都会更新状态,React 会重新渲染组件,并且每个组件实例都有自己的状态。
这也是为什么状态不使用原生 JS 的原因之一,因为原生 JS 的变量是全局的,无法区分不同组件的状态,容易造成变量冲突。
使用useState
的原因:
- 每个组件实例有自己独立的状态,避免复用时数据混乱
- 状态变化会触发组件自动更新,保持 UI 与数据一致
- React 内部管理状态生命周期,React 会根据组件的生命周期自动创建和销毁
useState
状态,避免内存泄漏或旧状态残留
使用 Hook
在 React 中,以 use
开头的函数被称为 Hook(钩子)。useState
是 React 提供的一个最常用的内置 Hook,它用于在函数组件中添加本地状态。
除了 useState
,React 还提供了许多其他内置 Hook,例如:
useEffect
:处理副作用(如数据获取、订阅等)useContext
:访问 React 上下文useReducer
:用于更复杂的状态逻辑useRef
:获取 DOM 引用或保存可变数据useMemo
、useCallback
:优化性能
你可以在 React 官方文档的 API 参考 中查看完整的 Hook 列表和用法。
除了使用内置 Hook,你还可以通过组合多个 现有Hook 编写 自定义 Hook,以提取逻辑、实现复用。例如:
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const onResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, []);
return width;
}
上述例子的 useWindowWidth
Hook 可以在任何组件中使用,获取当前窗口宽度并自动更新。
Hook 的使用有一些特别的规则,比普通函数更严格,目的是让 React 能可靠地追踪 Hook 的调用顺序和状态:
只能在函数组件或自定义 Hook 的顶层调用,不能在 if、for、函数嵌套中调用 Hook。
// 正确
function MyComponent() {
const [count, setCount] = useState(0); // ✅ 顶层调用
}
// 错误
if (someCondition) {
const [count, setCount] = useState(0); // ❌ 不允许
}
不能在普通的 JavaScript 函数中调用,Hook 只能在函数组件或自定义 Hook 中使用,不能在普通工具函数中调用。
Hook 名必须以 use
开头,这是一个约定,也帮助 React 检测 Hook 的使用是否合规。
如果你需要在条件或循环中使用 Hook,比如你想在某些条件下使用某个状态 Hook,应该将这部分逻辑提取为一个新的组件或自定义 Hook。
组件间共享数据
为了在组件间共享数据,可以将状态和方法提升到它们的共同父组件中,然后通过 props 传递给子组件。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>共同更新的计数器</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
点了 {count} 次
</button>
);
}
onClick
实际是 MyApp
组件中的 handleClick
函数,它会更新 count
状态,再将新的 count
值传递给子组件 MyButton
。这样,两个按钮就可以共享同一个计数器状态。
通过上移状态到共同组件实现的组件数据共享叫做 状态提升。
数据模型
在React中,构建用户界面的核心是管理数据。为了实现这一点,React提供了两种基本的数据模型:props 和 state。
props
props (properties的缩写) 是从父组件传递给子组件的数据。它们可以被看作是组件的配置项或参数,用于定制组件的外观和行为。props是只读的,这意味着一个组件接收到props后,不应该也无法直接修改它。这种不可变性是React单向数据流原则的体现,确保数据从父组件流向子组件,使得数据管理和组件行为更易于预测和调试。它们的主要作用是实现组件的复用性,允许同一个组件在不同的上下文中被渲染,同时展示不同的数据或样式。props 使得组件像函数一样,给定相同的输入(props),总是产生相同的输出(渲染结果)。
state
state 则是一个组件内部私有的数据集合,它代表了组件在某个特定时间点的状态。与props不同,state是可变的,但其变化必须通过特定的React API(在类组件中是this.setState()
,在函数组件中是useState
Hook)来管理和更新。state 主要用于处理那些随时间或用户交互而变化的数据。例如,一个计数器的当前值、一个输入框的当前文本、或一个开关组件的开启/关闭状态,这些都适合存储在组件的state中。当组件的state发生变化时,React会自动重新渲染该组件及其子组件,以反映最新的状态。这使得React能够高效地响应用户操作和数据更新,构建出动态和交互式的用户界面。
简而言之,props 用于组件之间的数据传递和配置,是外部赋予的、不可变的;而 state 则用于组件内部管理自身随时间变化的数据,是组件内部私有的、可变的。它们共同构成了React组件灵活且强大的数据管理机制。
贡献者
更新日志
7eec2
-Document organization于9de0b
-全局优化于b1c4a
-文档迁移于