React 入门

React 是由 Meta(前 Facebook)开发并开源的 JavaScript UI 库,专注于构建用户界面。它于 2013 年开源,目前已成为最流行的前端技术之一。 react 核心概念 组件(Component) React 的核心单元是组件(Component)。组件是一个返回 UI 描述的函数(或类),可以像拼积木一样组合成复杂的界面。 function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } 组件分为两类: 函数组件:现代 React 的主流写法,配合 Hooks 使用 类组件:早期写法,新项目不推荐使用 JSX JSX 是 JavaScript 的语法扩展,允许在 JS 文件中写类似 HTML 的结构。它不是 HTML,会被编译工具(如 Babel、SWC)编译为 React.createElement() 调用。 const element = <div className="container">Hello</div>; // 编译后等价于: const element = React.createElement("div", { className: "container" }, "Hello"); 详见:JSX 介绍 Props Props(属性)是组件的输入,由父组件传入,在子组件内部是只读的。 function Button({ label, onClick }) { return <button onClick={onClick}>{label}</button>; } // 使用 <Button label="提交" onClick={() => console.log("clicked")} /> State State(状态)是组件内部管理的可变数据。状态变化会触发组件重新渲染。 import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>当前计数:{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); } 虚拟 DOM React 在内存中维护一棵虚拟 DOM 树。每次状态更新时,React 通过 Diffing 算法对比新旧虚拟 DOM,计算出最小变更集,再批量更新真实 DOM,从而提升性能。 ...

Created 17176-05-17 · Updated 16166-06-16 · 2 min · 353 words · -

React 状态管理:Zustand、Jotai 与 Redux 对比

什么是状态管理,它解决什么问题 React 的数据流是单向的:数据通过 Props 从父组件流向子组件。这在小型应用中很好用,但随着应用规模扩大,会遇到两个典型痛点: Prop Drilling(属性透传) 同一份数据需要从顶层组件一层一层往下传,中间层组件本身并不使用这个数据,却不得不接收并转发它。组件层级越深,代码越难维护。 App(持有 user 状态) └─ Layout └─ Sidebar └─ UserAvatar(需要 user)← 要传三层 props 跨组件状态同步困难 当两个没有父子关系的组件需要访问同一份数据时,只能把状态提升到它们共同的祖先组件,然后再层层传下去。状态越分散,同步越容易出 bug。 状态管理库的解法 把共享状态提取到组件树之外的独立 Store,任何组件都可以直接订阅和修改,不需要层层传递 Props。 Store(独立于组件树) ↗ ↗ ComponentA ComponentB React 主流状态管理方案对比 库 定位 包大小 学习曲线 Zustand 轻量、直觉式 API ~1 KB 低 Jotai 原子化状态,细粒度订阅 ~3 KB 低 Redux Toolkit 功能完整,适合大型项目 ~20 KB 高 Zustand Zustand 是目前最流行的轻量状态管理库,API 极简,和 Vue 的 Pinia 非常相似。 创建 Store: ...

Created 18186-05-18 · Updated 18186-05-18 · 4 min · 685 words · -

React 函数组件与类组件

React 有两种组件写法:函数组件(Function Component) 和 类组件(Class Component)。现代 React 项目几乎全面使用函数组件,类组件属于历史遗留写法。 函数组件 函数组件就是一个普通的 JavaScript 函数,接收 Props,返回 JSX。 function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } // 也可以用箭头函数 const Greeting = ({ name }) => <h1>Hello, {name}!</h1>; React 16.8 引入 Hooks 之后,函数组件可以使用状态和生命周期,成为主流写法。 类组件 类组件通过继承 React.Component 实现,必须定义 render() 方法返回 JSX。 import { Component } from "react"; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } 有状态的类组件: class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return ( <div> <p>计数:{this.state.count}</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> +1 </button> </div> ); } } 同一功能的对比 以一个带状态的计数器为例,对比两种写法的差异: 类组件写法: class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); // 必须手动绑定 this } componentDidMount() { document.title = `计数:${this.state.count}`; } componentDidUpdate() { document.title = `计数:${this.state.count}`; } componentWillUnmount() { document.title = "App"; } handleClick() { this.setState({ count: this.state.count + 1 }); } render() { return ( <button onClick={this.handleClick}> 计数:{this.state.count} </button> ); } } 函数组件写法: ...

Created 17176-05-17 · Updated 17176-05-17 · 3 min · 481 words · -

React Hooks 详解

Hook 是 React 16.8 引入的一类特殊函数,命名以 use 开头。它让函数组件拥有了原本只有类组件才有的能力:状态管理、生命周期、跨组件共享逻辑。 为什么需要 Hook React 16.8 之前,函数组件只能做纯渲染,没有状态、没有生命周期。要用这些功能必须写类组件,但类组件存在几个痛点: this 绑定容易出错 生命周期方法(componentDidMount / componentDidUpdate)把不相关的逻辑强行塞在一起 状态逻辑难以在组件之间复用 Hook 彻底解决了这些问题,现代 React 项目基本全面使用函数组件 + Hook。 Hook 使用规则 这两条规则必须严格遵守,否则会导致 Bug。 只在函数组件或自定义 Hook 的顶层调用 Hook,不能在条件语句、循环、嵌套函数中调用 只在 React 函数中调用 Hook,不能在普通 JS 函数中调用 // ❌ 错误:在条件语句中调用 if (condition) { const [value, setValue] = useState(0); } // ✅ 正确:在顶层调用 const [value, setValue] = useState(0); if (condition) { setValue(1); } 内置 Hook useState 管理组件的局部状态。 const [state, setState] = useState(initialValue); state:当前状态值 setState:更新状态的函数,调用后触发重渲染 initialValue:初始值,也可以传入一个函数(懒初始化) import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>计数:{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> <button onClick={() => setCount(prev => prev - 1)}>-1</button> </div> ); } 函数式更新:当新状态依赖上一个状态时,推荐传函数给 setState,避免闭包陷阱: ...

Created 17176-05-17 · Updated 17176-05-17 · 4 min · 675 words · -