跳到主要内容

React 学习之旅 2 - 基础篇 2

概述

本文继续介绍 React 的基础知识,包括事件响应、界面更新、组件与 Props、状态管理、表单处理、条件渲染和列表渲染等内容。

响应事件

通过在组件中声明事件处理函数来响应事件:

DEMO: react-journey/02/event.html

function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return <button onClick={handleClick}>点我</button>;
}

function MyApp() {
return <MyButton />;
}

注意:只需传递函数给事件,不需要调用函数!

更新界面

如果需要组件“记住信息”,则需要引入 state

DEMO: react-journey/02/state.html

const { useState } = React;

function MyApp() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<MyApp />);

useState 说明:

  • useState() 中可以获得两样东西:当前的 state(count),以及用于更新它的函数 setState(setCount
  • 第一次在 useState() 传的值是默认值,如:本例中 count 的初始值为 0
  • 如果多次渲染同一个组件,则每个组件都有拥有自己的 state,互不影响

使用 Hook

什么是 Hook?

  • 以 use 开头的函数被称为 Hook
  • useState 是 React 提供的一个内置 Hook,还有 其他内置的 Hook
  • 可以组合现有的 Hook 来创建自己的 Hook
  • Hook 只能在组件顶层调用

如何理解“Hook 只能在组件顶层调用?”

  • “顶层”指的是组件的函数体最外层,也就是在组件的函数定义中,不在任何条件语句、循环、嵌套函数或其他代码块内部
  • Hook 必须在顶层使用,以确保 React 能够正确跟踪和管理 Hook 的状态
  • 如果需要条件逻辑,可以将条件判断放在 Hook 内部,而不是在 Hook 的调用上
// ✅ 正确示例
function MyComponent() {
const [count, setCount] = useState(0); // 顶层
useEffect(() => {
console.log("Component mounted");
}, []); // 顶层
return <div>{count}</div>;
}
// ❌ 错误示例
function MyComponent() {
if (someCondition) {
const [count, setCount] = useState(0); // 错误:在条件语句中
}
useEffect(() => {
const [name, setName] = useState(""); // 错误:在嵌套函数中
}, []);
return <div>{count}</div>;
}

Q:那么,如果按错误示例去写,页面会有什么报错信息吗? A:会,信息如下:

组件间共享数据

前面说到,state 放在 MyBtn 组件(子组件)里面,即使多次渲染同一个组件,仍互不影响

但是很多情况下,你需要不同组件共享同一个数据

这时候,你就需要把 state 提升到父组件(状态提升),然后把值向下传递给不同子组件(prop 传值

DEMO: react-journey/02/shared-state.html

function MyApp() {
// 状态声明
const [count, setCount] = useState(0);
// 点击方法
const handleClick = () => {
setCount(count + 1);
};
return (
<>
<MyBtn count={count} onClick={handleClick} />
<MyBtn count={count} onClick={handleClick} />
<MyBtn count={count} onClick={handleClick} />
</>
);
}

// 传入在父组件定义的状态变量及点击方法到子组件
function MyBtn({ count, onClick }) {
return (
<div>
<h1>Count: {count}</h1>
<button onClick={onClick}>Increment</button>
</div>
);
}

资源

参考