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

从React Tutorial到现代React:如何将经典示例升级到Hooks和函数组件

从React Tutorial到现代React:如何将经典示例升级到Hooks和函数组件

【免费下载链接】react-tutorialCode from the React tutorial.项目地址: https://gitcode.com/gh_mirrors/re/react-tutorial

React Tutorial是Facebook官方提供的经典React学习示例,展示了如何使用React构建一个简单的评论应用。然而,这个示例使用的是ES5语法和React.createClass,与现代React开发实践已有较大差距。本文将为你展示如何将这个经典示例升级到现代React,使用Hooks和函数组件,让你的代码更简洁、更易维护。😊

为什么需要升级到现代React?

React Tutorial示例虽然经典,但它使用的是React 15.3.0版本和ES5语法。现代React开发已经全面转向函数组件和Hooks,这带来了以下优势:

  • 代码更简洁:函数组件比类组件更简洁,减少了样板代码
  • 逻辑复用更简单:Hooks提供了更好的逻辑复用机制
  • 学习曲线更平缓:函数组件更接近普通JavaScript函数
  • 性能优化更容易:React团队推荐使用函数组件进行优化

项目结构概览

首先让我们了解一下原始项目的结构:

gh_mirrors/re/react-tutorial/ ├── public/ │ ├── css/ │ │ └── base.css │ ├── scripts/ │ │ └── example.js │ └── index.html ├── comments.json ├── package.json └── server.js

核心的React代码位于public/scripts/example.js,这是一个使用React.createClass的ES5实现。

升级步骤详解

1. 升级依赖包

首先需要更新package.json中的依赖。原始项目使用React 15.3.0,我们需要升级到支持Hooks的版本:

{ "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" } }

2. 将Comment组件转换为函数组件

原始的Comment组件使用React.createClass:

var Comment = React.createClass({ rawMarkup: function() { var md = new Remarkable(); var rawMarkup = md.render(this.props.children.toString()); return { __html: rawMarkup }; }, render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={this.rawMarkup()} /> </div> ); } });

升级后的函数组件版本:

import React from 'react'; function Comment({ author, children }) { const rawMarkup = () => { const md = new Remarkable(); const rawMarkup = md.render(children.toString()); return { __html: rawMarkup }; }; return ( <div className="comment"> <h2 className="commentAuthor"> {author} </h2> <span dangerouslySetInnerHTML={rawMarkup()} /> </div> ); }

3. 使用useState Hook管理状态

原始的CommentForm组件使用getInitialState管理状态:

var CommentForm = React.createClass({ getInitialState: function() { return {author: '', text: ''}; }, handleAuthorChange: function(e) { this.setState({author: e.target.value}); }, handleTextChange: function(e) { this.setState({text: e.target.value}); }, // ... 其他方法 });

使用useState Hook的现代版本:

import React, { useState } from 'react'; function CommentForm({ onCommentSubmit }) { const [author, setAuthor] = useState(''); const [text, setText] = useState(''); const handleSubmit = (e) => { e.preventDefault(); const trimmedAuthor = author.trim(); const trimmedText = text.trim(); if (!trimmedText || !trimmedAuthor) { return; } onCommentSubmit({ author: trimmedAuthor, text: trimmedText }); setAuthor(''); setText(''); }; return ( <form className="commentForm" onSubmit={handleSubmit}> <input type="text" placeholder="Your name" value={author} onChange={(e) => setAuthor(e.target.value)} /> <input type="text" placeholder="Say something..." value={text} onChange={(e) => setText(e.target.value)} /> <input type="submit" value="Post" /> </form> ); }

4. 使用useEffect Hook处理副作用

原始的CommentBox组件使用componentDidMount和setInterval:

var CommentBox = React.createClass({ componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, // ... 其他方法 });

使用useEffect Hook的现代版本:

import React, { useState, useEffect } from 'react'; function CommentBox({ url, pollInterval = 2000 }) { const [comments, setComments] = useState([]); const loadCommentsFromServer = async () => { try { const response = await fetch(url); const data = await response.json(); setComments(data); } catch (error) { console.error('Failed to load comments:', error); } }; useEffect(() => { loadCommentsFromServer(); const intervalId = setInterval(loadCommentsFromServer, pollInterval); return () => clearInterval(intervalId); }, [url, pollInterval]); const handleCommentSubmit = async (comment) => { // 乐观更新 const optimisticComment = { ...comment, id: Date.now() }; const newComments = [...comments, optimisticComment]; setComments(newComments); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(comment), }); const data = await response.json(); setComments(data); } catch (error) { // 回滚到原始状态 setComments(comments); console.error('Failed to submit comment:', error); } }; return ( <div className="commentBox"> <h1>Comments</h1> <CommentList comments={comments} /> <CommentForm onCommentSubmit={handleCommentSubmit} /> </div> ); }

5. 使用useCallback优化性能

对于需要传递给子组件的回调函数,可以使用useCallback进行优化:

import React, { useState, useEffect, useCallback } from 'react'; function CommentBox({ url, pollInterval = 2000 }) { const [comments, setComments] = useState([]); const loadCommentsFromServer = useCallback(async () => { try { const response = await fetch(url); const data = await response.json(); setComments(data); } catch (error) { console.error('Failed to load comments:', error); } }, [url]); const handleCommentSubmit = useCallback(async (comment) => { // ... 处理评论提交逻辑 }, [comments, url]); useEffect(() => { loadCommentsFromServer(); const intervalId = setInterval(loadCommentsFromServer, pollInterval); return () => clearInterval(intervalId); }, [loadCommentsFromServer, pollInterval]); // ... 渲染逻辑 }

完整的现代React实现

将所有组件整合后,完整的现代React版本如下:

import React, { useState, useEffect, useCallback } from 'react'; function Comment({ author, children }) { const rawMarkup = () => { const md = new Remarkable(); const rawMarkup = md.render(children.toString()); return { __html: rawMarkup }; }; return ( <div className="comment"> <h2 className="commentAuthor">{author}</h2> <span dangerouslySetInnerHTML={rawMarkup()} /> </div> ); } function CommentList({ comments }) { return ( <div className="commentList"> {comments.map((comment) => ( <Comment key={comment.id} author={comment.author}> {comment.text} </Comment> ))} </div> ); } function CommentForm({ onCommentSubmit }) { const [author, setAuthor] = useState(''); const [text, setText] = useState(''); const handleSubmit = (e) => { e.preventDefault(); const trimmedAuthor = author.trim(); const trimmedText = text.trim(); if (!trimmedText || !trimmedAuthor) { return; } onCommentSubmit({ author: trimmedAuthor, text: trimmedText }); setAuthor(''); setText(''); }; return ( <form className="commentForm" onSubmit={handleSubmit}> <input type="text" placeholder="Your name" value={author} onChange={(e) => setAuthor(e.target.value)} /> <input type="text" placeholder="Say something..." value={text} onChange={(e) => setText(e.target.value)} /> <input type="submit" value="Post" /> </form> ); } function CommentBox({ url, pollInterval = 2000 }) { const [comments, setComments] = useState([]); const loadCommentsFromServer = useCallback(async () => { try { const response = await fetch(url); const data = await response.json(); setComments(data); } catch (error) { console.error('Failed to load comments:', error); } }, [url]); const handleCommentSubmit = useCallback(async (comment) => { const optimisticComment = { ...comment, id: Date.now() }; const newComments = [...comments, optimisticComment]; setComments(newComments); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(comment), }); const data = await response.json(); setComments(data); } catch (error) { setComments(comments); console.error('Failed to submit comment:', error); } }, [comments, url]); useEffect(() => { loadCommentsFromServer(); const intervalId = setInterval(loadCommentsFromServer, pollInterval); return () => clearInterval(intervalId); }, [loadCommentsFromServer, pollInterval]); return ( <div className="commentBox"> <h1>Comments</h1> <CommentList comments={comments} /> <CommentForm onCommentSubmit={handleCommentSubmit} /> </div> ); } export default CommentBox;

服务器端升级

原始项目使用server.js作为后端服务器,支持多种语言实现。现代React应用通常与现代化的后端API配合使用。你可以保持现有的服务器代码不变,或者升级到更现代的Node.js框架如Express 4.x。

项目配置优化

除了代码升级,你还可以进行以下配置优化:

  1. 使用Create React App:快速搭建现代React项目结构
  2. 配置ESLint和Prettier:保持代码风格一致
  3. 添加TypeScript支持:提高代码类型安全性
  4. 使用React Router:如果需要多页面功能
  5. 集成状态管理:如Redux或Context API

总结

通过本文的指导,你已经学会了如何将经典的React Tutorial示例升级到现代React。从React.createClass到函数组件,从生命周期方法到Hooks,从jQuery.ajax到fetch API,这些升级让你的代码更加现代化、简洁和易于维护。

升级后的代码具有以下优势:

  • ✅ 使用函数组件,代码更简洁
  • ✅ 使用Hooks,逻辑更清晰
  • ✅ 使用现代JavaScript语法(ES6+)
  • ✅ 更好的性能优化潜力
  • ✅ 更符合当前React最佳实践

现在你可以将这个升级技巧应用到自己的项目中,享受现代React开发带来的便利和效率提升!🚀

下一步学习建议

如果你已经掌握了基本的Hooks使用,可以进一步学习:

  1. 自定义Hooks:创建可复用的逻辑
  2. Context API:管理全局状态
  3. React Router v6:现代路由解决方案
  4. React Query或SWR:数据获取和缓存
  5. 性能优化技巧:如React.memo、useMemo、useCallback

记住,React生态系统在不断进化,保持学习和实践是成为优秀React开发者的关键。祝你在React的学习和开发之路上越走越远!🎉

【免费下载链接】react-tutorialCode from the React tutorial.项目地址: https://gitcode.com/gh_mirrors/re/react-tutorial

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/533219/

相关文章:

  • 从零到一:STORM如何用AI大模型自动生成高质量维基百科式文章
  • Laravel Entrust权限管理:构建强大角色权限系统的终极指南
  • ElementUI el-date-picker 时间范围选择器:从日期到时分秒的精细化控制
  • 微信机器人技术演进:从传统wxBot到现代框架的深度解析
  • 别让编译器“优化”掉你的bug:从datalab实验深入理解C语言未定义行为(UB)的实战陷阱
  • SDMatte效果惊艳展示:4K分辨率玻璃器皿全图抠取无锯齿无断边
  • 如何快速掌握React Autosuggest:从架构解析到实战应用的完整指南
  • 上海有哪些咨询公司能处理战略定位模糊问题靠谱吗 - 工业品网
  • 连续毡(树脂导流)费用大概多少钱,有哪些靠谱厂家 - 工业品网
  • uView 2.0样式穿透实战:从‘改不动’到‘随心改’,一份给uni-app新手的保姆级排雷指南
  • Go后端生产级实践:架构、工程化、性能、质量四维度攻坚指南(2026前瞻版)
  • 学号20253908 2025-2026-2 《网络攻防实践》第1周作业
  • UdonSharp:将C代码转换为VRChat互动世界的桥梁
  • 圣女司幼幽-造相Z-Turbo生成作品的高清化处理:对比不同超分辨率算法效果
  • 从企业分支互联到云专线:华为/华三设备上VPWS与VPLS到底该怎么选?
  • Linux文件权限进阶:为什么你的passwd命令能修改shadow文件?
  • 12 用docker使用三种操作系统
  • SVGAPlayer-Android入门指南:5分钟学会在Android应用中播放After Effects动画
  • Qt Model/View实战:5分钟搞定一个可编辑表格(附完整代码)
  • 平行数字世界的智能体模拟:MiroFish群体智能引擎探索指南
  • Windows 常用网络与系统命令
  • Leecode Hot100
  • MogFace模型JavaScript交互开发:实现浏览器端人脸检测Demo
  • free-programming-resources社区贡献指南:如何参与项目完善
  • obs-multi-rtmp:突破平台壁垒的直播分发解决方案
  • React Native Testing Library 源码解析:理解测试运行原理
  • Windows用户的fMRI质控救星:除了DIPABI,还有哪些工具能帮你做图像质量评估?
  • 运算放大器输入偏置电流与失调电流:从定义到实战误差分析与应对
  • Flux Sea Studio 多风格效果对比:从写实主义到梦幻插画
  • 入户门品牌怎么选?从浙江群邦门业的实践看高端装甲门的升级路线 - 企师傅推荐官