☰
React 入门笔记(三):列表渲染、Key 与事件处理
2026/10/14 19:12:24 网站建设 项目流程

这篇解决三个问题:怎么把数组渲染成一排标签、为什么要有 Key、以及怎么处理用户的点击输入等事件。


一、渲染列表

实际开发中经常遇到这种情况:后端给你一个数组,比如水果列表['苹果', '香蕉', '橘子'],你需要在页面上显示成一排列表项。

这时候用数组的map()方法:遍历数组每一项,每一项返回一个 JSX 元素。

function FruitList() { const fruits = ["苹果", "香蕉", "橘子"]; return ( <ul> {fruits.map((fruit) => ( <li>{fruit}</li> ))} </ul> ); }

外面包一层{}是因为要在 JSX 里写 JavaScript 表达式。map 遍历每一个水果,生成一个<li>标签,React 自动帮你拼成一排。

如果数组里是对象呢?比如商品列表:

function ProductList() { const products = [ { id: 1, name: "手机", price: 3999 }, { id: 2, name: "电脑", price: 8999 }, { id: 3, name: "耳机", price: 999 }, ]; return ( <div> {products.map((product) => ( <div className="product"> <h3>{product.name}</h3> <p>价格:¥{product.price}</p> </div> ))} </div> ); }

二、列表的 Key 键

上面的代码跑起来其实会有警告。打开浏览器控制台,你会看到一条黄色的警告:“Each child in a list should have a unique key prop”。

2.1 Key 是干嘛的?

想象你排队买奶茶,每个人都有个号码牌。队伍顺序变了(有人插队、有人走了),工作人员靠号码牌认出 “哦这是刚才那个人”,而不是把所有人都重新认一遍。

Key 就是列表项的号码牌。React 更新列表的时候,靠 Key 判断哪一项是新的、哪一项动过了,这样只改变化的部分,性能更好。

正确写法是给每个列表项加一个key属性:

function ProductList() { const products = [ { id: 1, name: "手机", price: 3999 }, { id: 2, name: "电脑", price: 8999 }, { id: 3, name: "耳机", price: 999 }, ]; return ( <div> {products.map((product) => ( <div key={product.id} className="product"> <h3>{product.name}</h3> <p>价格:¥{product.price}</p> </div> ))} </div> ); }

用数据里的唯一 id 当 key,就不会报警告了。

2.2 为什么不能用 index 当 Key?

新手很容易图省事,直接用数组下标当 key:

// ❌ 不推荐 {fruits.map((fruit, index) => ( <li key={index}>{fruit}</li> ))}

为什么不好?举个例子:队伍有三个人 [A, B, C],下标分别是 0、1、2。现在 A 走了,变成 [B, C]。

如果用下标当 key:B 原来是下标 1,现在变成下标 0 了。React 会以为 “哦下标 0 的内容从 A 变成 B 了,下标 1 从 B 变成 C 了,下标 2 的 C 没了”。结果三个元素全部重新渲染,性能浪费。

而且更严重的是,如果列表项里面有输入框、有自己的状态,顺序一变状态就会错乱。

记住:Key 必须用数据本身的唯一标识,比如 id,不能用数组下标。

只有一种情况可以用 index:列表是纯静态的,永远不会增删排序。但这种情况很少。


三、组件样式怎么加

React 里给组件加样式,有三种常用方式。

3.1 行内样式

直接在标签上写style属性,注意要写成对象:

function Button() { return ( <button style={{ color: "white", backgroundColor: "blue", padding: "8px 16px" }}> 点我 </button> ); }

适合临时、动态的样式。如果样式固定,还是写外部 CSS 比较好。

3.2 外部 CSS 文件

最常用的方式。写一个.css文件,然后在组件里 import 进来。

/\* Button.css \*/ .button { color: white; background-color: blue; padding: 8px 16px; border: none; border-radius: 4px; }
import "./Button.css"; function Button() { return <button className="button">点我</button>; }

缺点是所有组件共享同一个 CSS 作用域,A 组件的样式可能不小心影响 B 组件。

3.3 CSS Modules

为了解决样式污染问题,可以用 CSS Modules。把文件名改成Button.module.css:

/\* Button.module.css \*/ .button { color: white; background-color: blue; padding: 8px 16px; }

然后这样用:

import styles from "./Button.module.css"; function Button() { return <button className={styles.button}>点我</button>; }

这样每个组件的样式自动加了后缀,互不干扰,相当于 “样式私有化”。


四、事件处理

用户点按钮、输入文字、滚动页面,这些都是事件。React 处理事件的方式和原生 JS 很像,但有几个区别。

4.1 基本写法

function Button() { function handleClick() { alert("你点了我"); } return <button onClick={handleClick}>点我</button>; }

注意几个关键点:

  1. 事件名用驼峰:onClick而不是onclick

  2. 传函数而不是字符串:onClick={handleClick}而不是onclick="handleClick()"

  3. 不要加括号:写onClick={handleClick}是把函数传进去,点击的时候才执行。如果写成onClick={handleClick()},就变成页面一加载就立刻执行了

4.2 传参数

如果事件处理函数需要参数,怎么办?不能直接写括号,那会立刻执行。要用箭头函数包一层:

function TodoList() { function handleDelete(id) { console.log("删除了", id); } return ( <div> <button onClick={() => handleDelete(1)}>删除第1条</button> <button onClick={() => handleDelete(2)}>删除第2条</button> </div> ); }

箭头函数里调用 handleDelete,把参数传进去。这样只有点击的时候才执行。


本篇小结

  • 渲染列表用map()遍历数组,每一项返回一个 JSX 元素

  • 每个列表项必须加key属性,用数据的唯一 id,不能用 index

  • 加样式三种方式:行内 style 对象、外部 CSS、CSS Modules

  • 事件处理:事件名驼峰、传函数不加括号、要传参数用箭头函数包一层

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询