当前位置: 首页 > news >正文

React.memo 小练习题 + 参考答案

🧩 React.memo 小练习题 + 参考答案


练习 1:基本使用

题目
创建一个父组件,里面有两个状态:countmessage
父组件渲染一个子组件 Message,它只接收 message 作为 props,并在渲染时打印 "Message render"
点击按钮改变 count,观察子组件是否重新渲染。
React.memo 优化 Message,观察差异。

答案代码:

import React, { useState } from "react";const Message = React.memo(({ message }) => {console.log("Message render");return <h2>{message}</h2>;
});export default function App() {const [count, setCount] = useState(0);const [message, setMessage] = useState("Hello");return (<div><h1>Count: {count}</h1><Message message={message} /><button onClick={() => setCount(count + 1)}>Increment Count</button><button onClick={() => setMessage(message + "!")}>Change Message</button></div>);
}

练习 2:浅比较的局限性

题目
父组件中维护一个 user = { name: "Tom" },把它作为 props 传给 UserCard
点击按钮时执行 setUser({ name: "Tom" })
观察即使数据没变,子组件还是会重新渲染。
尝试用 useMemo 固定对象引用,避免重新渲染。

答案代码:

import React, { useState, useMemo } from "react";const UserCard = React.memo(({ user }) => {console.log("UserCard render");return <h2>User: {user.name}</h2>;
});export default function App() {const [count, setCount] = useState(0);// ❌ 没优化// const user = { name: "Tom" };// ✅ 优化const user = useMemo(() => ({ name: "Tom" }), []);return (<div><h1>Count: {count}</h1><UserCard user={user} /><button onClick={() => setCount(count + 1)}>Increment Count</button></div>);
}

练习 3:结合 useCallback

题目
父组件定义一个回调函数 handleClick,传给子组件 ButtonChild
不使用 useCallback 时,子组件每次都会重新渲染。
useCallback 包装后,子组件不再重复渲染。

答案代码:

import React, { useState, useCallback } from "react";const ButtonChild = React.memo(({ onClick }) => {console.log("ButtonChild render");return <button onClick={onClick}>Child Button</button>;
});export default function App() {const [count, setCount] = useState(0);// ❌ 每次 App 渲染都会生成新函数// const handleClick = () => console.log("clicked");// ✅ useCallback 固定引用const handleClick = useCallback(() => console.log("clicked"), []);return (<div><h1>Count: {count}</h1><ButtonChild onClick={handleClick} /><button onClick={() => setCount(count + 1)}>Increment Count</button></div>);
}

练习 4:列表优化

题目
创建一个父组件,渲染 100 个用户,每个用户是一个子组件 UserRow
点击“刷新时间”按钮,观察整个列表是否重新渲染。
UserRow 添加 React.memo,避免不必要的渲染。

答案代码:

import React, { useState } from "react";const UserRow = React.memo(({ name }) => {console.log("Render UserRow:", name);return <li>{name}</li>;
});export default function App() {const [time, setTime] = useState(Date.now());const users = Array.from({ length: 100 }, (_, i) => `User ${i + 1}`);return (<div><h1>Time: {time}</h1><button onClick={() => setTime(Date.now())}>Refresh Time</button><ul>{users.map((u) => (<UserRow key={u} name={u} />))}</ul></div>);
}

练习 5:自定义比较函数

题目
创建一个子组件 Profile,接收 nameage
要求:只有 age 改变时才重新渲染。
使用 React.memo 的第二个参数实现。

答案代码:

import React, { useState } from "react";const Profile = React.memo(({ name, age }) => {console.log("Profile render");return (<div><h2>{name}</h2><p>Age: {age}</p></div>);},(prevProps, nextProps) => {return prevProps.age === nextProps.age; // 只在 age 改变时重新渲染}
);export default function App() {const [name, setName] = useState("Tom");const [age, setAge] = useState(20);return (<div><Profile name={name} age={age} /><button onClick={() => setName(name + "!")}>Change Name</button><button onClick={() => setAge(age + 1)}>Increment Age</button></div>);
}

练习 6:性能对比(进阶)

题目
渲染一个 5000 行的大列表,每一行是 ItemRow
点击按钮时更新一个无关的状态,看看没有 React.memo 时所有子组件是否重新渲染。
加上 React.memo 后,对比性能变化。

答案代码:

import React, { useState } from "react";const ItemRow = React.memo(({ value }) => {console.log("Render:", value);return <div>{value}</div>;
});export default function App() {const [tick, setTick] = useState(0);const items = Array.from({ length: 5000 }, (_, i) => `Item ${i}`);return (<div><h1>Tick: {tick}</h1><button onClick={() => setTick(tick + 1)}>Update Tick</button>{items.map((item) => (<ItemRow key={item} value={item} />))}</div>);
}

文章转载自:

http://eCfpaETI.snrbL.cn
http://OGLfZcdv.snrbL.cn
http://EhGbIGkO.snrbL.cn
http://yngWDWqB.snrbL.cn
http://AXZAnxWI.snrbL.cn
http://il2M8mlr.snrbL.cn
http://J59xHYhB.snrbL.cn
http://Ji4qtGMX.snrbL.cn
http://BCxbdvLJ.snrbL.cn
http://ZwOqOPLD.snrbL.cn
http://ffFW6NmX.snrbL.cn
http://ZBJItLIw.snrbL.cn
http://ulEPZ6LM.snrbL.cn
http://8wANy7jT.snrbL.cn
http://1gHkhY0d.snrbL.cn
http://2k37uqRx.snrbL.cn
http://MrmFKRkk.snrbL.cn
http://J6T50r1L.snrbL.cn
http://QiqKCEXl.snrbL.cn
http://TK7dovjf.snrbL.cn
http://ffkaBQpF.snrbL.cn
http://fNcVwiMf.snrbL.cn
http://Oysx0YTC.snrbL.cn
http://iDUfVta6.snrbL.cn
http://0rT15F6H.snrbL.cn
http://VHCJNW0f.snrbL.cn
http://94GJs8Rd.snrbL.cn
http://ZdezCsxd.snrbL.cn
http://Tb4sJfOX.snrbL.cn
http://bbWd9QWR.snrbL.cn
http://www.dtcms.com/a/380981.html

相关文章:

  • Java 的即时编译器(JIT)优化编译探测技术
  • 《计算机网络安全》实验报告一 现代网络安全挑战 拒绝服务与分布式拒绝服务攻击的演变与防御策略(4)
  • 综合体EMS微电网能效管理系统解决方案
  • ARM2.(汇编语言)
  • 从“插件化“到“智能化“:解密Semantic Kernel中Microsoft Graph的架构设计艺术
  • TDengine 特殊函数 MODE() 用户手册
  • 导购类电商平台的安全架构设计:防刷单与反作弊系统实现
  • 阿里云可观测 2025 年 8 月产品动态
  • 阿里云监控使用
  • 九识智能与北控北斗合作研发的L4级燃气超微量高精准泄漏检测无人车闪耀服贸会,守护城市安全
  • vulhub漏洞复现-redis-4-unacc (redis未授权访问)
  • 数据库分库分表是考虑ShardingSphere 还是Mycat?
  • CSP认证练习题目推荐 (3)
  • R geo 然后读取数据的时候 make.names(vnames, unique = TRUE): invalid multibyte string 9
  • Linux:线程封装
  • 电动指甲刀技术方案概述
  • 机器人巡检与巡逻的区别进行详细讲解和对比
  • 程序内存中堆(Heap)和栈(Stack)的区别
  • 提高软件可靠性的思路
  • (1-10-2)MyBatis 进阶篇
  • ZedGraph库里实现坐标拖动图形的背景显示
  • SpringBoot应用开发指南:从入门到高级配置与自动装配原理
  • 怎么快速规划好旅行
  • 一带一路经济走廊及其途经城市图件
  • k8s的设计哲学
  • 城市污水管网流量监测方法
  • 计算机视觉进阶教学之特征检测
  • 基于OpenVinoSharp和PP-Vehicle的车辆检测
  • [论文阅读] 人工智能 | 软件工程 - 软件测试 | 从黑盒到透明:AUTOSTUB用进化算法打通符号执行的“最后一公里”
  • zmq源码分析之io_thread_t