您好,欢迎光临有路网!
React+Node.js开发实战:从入门到项目上线
QQ咨询:
有路璐璐:

React+Node.js开发实战:从入门到项目上线

  • 作者:袁林 尹皓 陈宁
  • 出版社:机械工业出版社
  • ISBN:9787111674146
  • 出版日期:2021年03月01日
  • 页数:0
  • 定价:¥99.00
  • 分享领佣金
    手机购买
    城市
    店铺名称
    店主联系方式
    店铺售价
    库存
    店铺得分/总交易量
    发布时间
    操作

    新书比价

    网站名称
    书名
    售价
    优惠
    操作

    图书详情

    内容提要
    《React Node.js开发实战:从入门到项目上线》站在全栈开发的角度,通过“开发技术 项目实战”的方式,由点到面,由浅入深,由前端到后端,逐步介绍React Node.js开发的全貌。 《React Node.js开发实战:从入门到项目上线》共10章,分为4篇。第1篇“React和Node.js基础”,主要介绍开发环境的搭建、常用开发工具的使用,以及React与Node.js开发基础知识;第2篇“打包部署和项目开发实战”,主要介绍构建与部署工具Webpack、Nginx和PM2的相关知识,并**介绍如何使用React Node.js开发单页面评论系统项目案例;第3篇“React和Node.js进阶”,主要介绍React与Node.js开发进阶知识,并**介绍如何使用React Node.js开发社区项目案例;第4篇“项目优化和服务端渲染”,主要介绍前后端项目优化的常用技巧,以提升系统的性能、用户体验和可靠性,并介绍SPA面临的服务端渲染问题及其解决方法,涉及Next.js与SEO等技术。 《React Node.js开发实战:从入门到项目上线》非常适合前端工程师、后端工程师及We
    文章节选
    第1章 准备:搭建React Node.js
    开发环境 工欲善其事,必先利其器。学习任何一门新技术、新语言,都需要从*基础的环境搭建开始。本章将从零开始搭建一个适合初学者的React Node.js开发环境。 本章的主要知识点包括: l 环境优势:聊一聊选择React Node.js技术的原因; l 环境搭建:详细介绍React Node.js开发环境的搭建过程; l 开发工具:介绍在日常开发中使用的IDE(Visual Studio Code)和调试工具(Chrome、Postman等)。 小知识:IDE(Integrated Development Environment,集成开发环境),是提供程序开发环境的应用程序,通常包括编辑器、编译器、调试器和图形用户界面等功能模块。熟练掌握IDE的使用,可以大大提升开发效率。 1.1 为什么选择React Node.js 开发技术和框架那么多,为什么选择React.js和Node.js技术呢?或者说,React.js和Node.js技术有哪些优势呢? %说明:为方便描述,本书后面除标题外的部分都以Node来代替Node.js,以React来代替React.js。 1.1.1 React的优势 React(https://zh-hans.reactjs.org/)是用于构建用户界面的JavaScript库。只需要对HTML和JavaScript有简单了解就可以使用React进行开发,因此,React作为前端开发工具越来越受到***的欢迎。 与其他框架相比,React具备以下优点: (1)快速学习曲线:React是一个非常简单且轻量的库,它只处理视图层。任何有JavaScript经验的开发人员都可以理解其基础知识,在阅读完官方教程后,基本上就可以开发Web应用程序。 (2)可重复使用的组件:React提供基于组件的结构,组件相当于积木,***可以创建按钮、复选框、列表等小组件,并组合这些组件形成较复杂的组件,然后再继续组合,直到根组件为止,这些组件就构成了开发的应用程序。 (3)基于虚拟DOM的快速渲染:当开发复杂用户交互的Web应用程序时,需要频繁操作DOM,而操作DOM的代价较高,因为频繁操作DOM会导致浏览器的重绘和重排,进而影响性能。 这也正是React要解决的核心问题之一,它使用虚拟DOM来解决这个问题。任何视图的更改首先反馈到虚拟DOM,然后通过算法比较虚拟DOM的先前和当前状态,得出状态变化和差异,*后将这些更改应用于DOM。 虚拟DOM大大减少了操作DOM的次数和修改DOM的范围,这也是React之所以高性能的主要原因。 1.1.2 Node.js的优势 Node(https://nodejs.org/zh-cn/)是一个基于Chrome V8引擎的JavaScript运行时环境。它是一种轻量级、可扩展、跨平台的代码执行方式。 小知识:Chrome V8是一个由Google开发的开源JavaScript引擎,用于Google Chrome及Chromium中。Chrome V8在运行之前会将JavaScript代码编译成机器代码而非字节码,以此提升程序性能。更进一步,Chrome V8使用了如内联缓存(Inline Caching)等方法来提高性能。有了这些功能,JavaScript程序与Chrome V8引擎的运行速度可媲美二进制编译的程序。 选择Node进行开发的优点主要包括: l 使用JavaScript语言开发,便于前端***快速学习和掌握; l 易于快速构建实时应用程序(例如,开发聊天室应用),并基于Express(https://expressjs. com/zh-cn/)、socket.io(https://socket.io/)等技术开发; l 快速发展的NPM扩展包(https://www.npmjs.com/)提供了丰富的工具和模块,极大地提高了开发效率; l 基于事件驱动的非阻塞I/O模型,使其具有很高的并发执行效率。 1.1.3 React Node.js组合的优势 基于React开发前端,再配合Node开发服务端应用,优势如下: l JavaScript语言可以同时为客户端和服务端编码,这也让前后端开发变得容易,扫清了开发语言上的障碍; l 使用JavaScript语言及Node开发环境和生态,让团队的技术栈能够实现*大化的共享,减少了协作沟通的代价; l 随着技术学习和迁移难度的降低,企业招聘、培训和用人等综合成本也开始下降。 综上所述,本书选择React和Node技术进行讲解,以便让更多的读者掌握全栈开发技术,具备完整项目的前后端问题解决能力。 下面正式开启React和Node的学习与开发之旅。 1.2 搭建Node.js环境 本节将搭建Node开发环境,搭建完成后通过一个简单示例来展示效果,使读者对Node有一个初步的认识。 %提示:关于Node开发的相关知识,会在第3章中详细介绍。 1.2.1 安装Node.js Node的安装有如下几种方式: l 通过源码编译安装; l 通过安装包安装; l 通过系统包管理器安装; l 通过Node版本管理工具安装。 其中,下载源码然后编译安装的方法比较复杂,通常情况下,选择其他方式安装Node即可满足开发需求。因此,下面将**介绍其他3种安装方法。 安装Node前,需要确定所安装的Node版本,笔者**安装*新的LTS版本。在本书写作时,Node的*新LTS版本是v12.14.*。 小知识:LTS(Long-Term Support,长期支持)是一种软件的产品生命周期政策,特别是对于开源软件,它增加了软件开发过程及软件版本周期的可靠度。 1.安装包 访问Node官网的下载地址(https://nodejs.org/zh-cn/download/),下载指定系统的安装包,如图1.1所示。 图1.1 访问Node官网下载安装包 下面以macOS系统为例(其他系统安装方式类似),介绍通过安装包安装Node的过程。 (1)下载macOS安装包文件node-v12.14.1.pkg。 (2)单击安装包开始安装,效果如图1.2所示。 图1.2 开始安装Node (3)按照提示依次单击Continue、Agree及Install按钮,直到安装成功,效果如图1.3所示。 图1.3 通过安装包成功安装Node (4)安装成功后,查看当前已安装的Node版本,验证安装是否成功,命令如下: node --version v12.14.1 在安装Node的同时还会安装Node包管理器NPM(Node Package Manager),查看其版本,命令如下: npm --version 6.13.4 小知识:软件包管理器是指自动安装、配置、卸载和升级软件包的工具组合。NPM是Node默认的以JavaScript编写的软件包管理器。 2.系统包管理 除了使用安装包安装Node之外,还可以使用当前操作系统的软件包管理器来安装Node。 l Windows系统的包管理器为Chocolatey(https://chocolatey.org/); l Linux的Ubuntu发行版的包管理器为APT(Advanced Packaging Tools); l macOS系统的包管理器为Homebrew(https://brew.sh/)。 下面以macOS系统为例(其他系统包管理器类似),介绍如何使用包管理器安装Node。 小知识:Homebrew是macOS系统默认的软件包管理器,使用Homebrew可以安装Apple没有预装但***需要的工具。更多关于Homebrew的介绍,可以访问其官网https://brew.sh/。 (1)安装Homebrew的命令很简单,具体如下: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/ install/master/install)" (2)验证已安装的Homebrew工具,命令如下: brew version Homebrew 2.1.6 (3)使用安装好的Homebrew来搜索和安装Node,命令如下: brew search node brew install node 3.版本管理器 除了上述安装方法外,更加灵活的方法是使用Node版本管理器进行安装。使用版本管理器可以实现在同一台机器上安装和切换不同版本的Node环境。 常见的Node版本管理器主要有: l nvm(https://github.com/nvm-sh/nvm); l n(https://github.com/tj/n)。 小知识:n的作者是TJ Holowaychuk,这是Node圈内的一位重量级人物,不仅开发了Node版本管理器n,还是Koa、Co、Express、Jade、Mocha、node-canvas和commander.js等知名开源项目的创建者和贡献者。 nvm和n的功能类似。下面就以nvm为例来介绍Node版本管理器的使用。 (1)安装nvm,安装命令很简单,具体如下: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash 也可以使用如下命令进行安装: wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash (2)根据提示进行如下操作: => Close and reopen your terminal to start using nvm or run the following to use it now: export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion (3)重启当前终端或直接运行上述命令。当然,*方便的办法是将上述命令添加到当前Shell的配置文件中,以macOS为例,可以添加到“~/.bashrc”文件中。 配置成功后便可以使用nvm命令安装并管理Node。 (4)查看可以安装的所有LTS版本,命令如下: nvm ls-remote --lts (5)安装*新的LTS版本v12.14.1,命令如下: nvm install v12.14.1 (6)查看本地已安装的Node版本,以及默认的Node版本等信息,命令如下: nvm ls (7)如果安装了多个Node版本,可以设置默认的Node版本,命令如下: nvm alias default v12.14.1 %提示:nvm命令和功能还有很多,读者可以参考其官网文档,网址为https://github.com/ nvm-sh/nvm。 1.2.2 常用工具1:NPM、CNPM和NRM 在Node环境搭建和开发的过程中,经常需要用到的工具还有NPM。因此,在学习Node开发之前,还需要熟练掌握包管理器的使用。 1.NPM 安装Node时同时会安装NPM,它主要有如下命令: # 初始化Node项目,生成package.json文件 npm init # 查看本地安装目录 npm root # 安装本地依赖包 npm install # 安装运行依赖包,并且将其保存至package.json文件中 npm install --save # 安装开发依赖包,并且将其保存至package.json文件中 npm install --save-dev # 更新本地依赖包 npm update # 查看本地依赖包 npm ls # 卸载本地依赖包 npm uninstall # 查看全局安装目录 npm root -g # 安装全局依赖包 npm install -g # 更新全局依赖包 npm update -g # 查看全局依赖包 npm ls -g # 卸载全局依赖包 npm uninstall -g # 查看依赖包信息 npm info # 执行scripts配置的命令 npm run 如果前期记不住这么多命令的话,可以使用NPM的帮助命令,具体如下: npm help 或 npm h 2.CNPM NPM安装包是从国外服务器上下载的,受网络因素影响较大,可能会出现异常。因此,国内的淘宝团队同步NPM实现了NPM的国内源。我们可以在使用NPM安装包时配置淘宝的国内源,命令如下: npm --registry=https://registry.npm.taobao.org 为了方便使用,淘宝团队不仅提供了上述镜像源,还开发了一个更易用的工具CNPM(https://npm.taobao.org/),不仅自动使用国内源,而且还支持gzip压缩。 因此可以安装CNPM来替代NPM,命令如下: npm install -g cnpm --registry=https://registry.npm.taobao.org 3.NRM 如果想要使用其他非淘宝的镜像源,还可以安装一款名为NRM(https://github.com/ Pana/nrm)的镜像源管理工具,命令如下: npm install -g nrm 然后查看所有可用的镜像源,命令如下: nrm ls npm -------- https://registry.npmjs.org/ yarn ------- https://registry.yarnpkg.com/ cnpm ------- http://r.cnpmjs.org/ * taobao ----- https://registry.npm.taobao.org/ nj --------- https://registry.nodejitsu.com/ npmMirror -- https://skimdb.npmjs.com/registry/ edunpm ----- http://registry.enpmjs.org/ *后设置想要使用的镜像源,命令如下: nrm use cnpm 1.2.3 常用工具2:YARN 除了NPM外,还可以使用一款叫作YARN的替代工具。 YARN(https://yarnpkg.com/)是Facebook(https://about.fb.com/)等公司开发的用于替换NPM的包管理工具。那么YARN有哪些优势足以替代NPM呢? l 速度超快:YARN缓存了每个曾经下载过的包,所以再次使用这些包时无须重复下载。同时,利用并行下载使资源利用率*大化,因此安装速度更快。 l ****:在执行代码之前,YARN会通过算法校验每个安装包的完整性。 l **可靠:使用详细、简洁的锁文件(yarn.lock)格式和明确的安装依赖包的算法,YARN能够保证在不同系统上无差异地工作。 %提示:除了上述优点,YARN还有许多有用的特性,读者可以自行参考官方文档,网址是https://yarn.bootcss.com/。 YARN的安装很简单,这里仍然以macOS系统为例,使用Homebrew包管理器来安装,具体命令如下: brew install yarn yarn --version 1.17.0 YARN的使用和NPM一样,非常容易上手,从NPM迁移到YARN的命令对照如表1.1所示。 表1.1 从NPM迁移到YARN的命令对照表 操 作 NPM命令 YARN命令 初始化Node项目 npm init yarn init 安装本地依赖包 npm install yarn 安装运行依赖包,并且保存至package.json文件中 npm install --save yarn add 安装开发依赖包,并且保存至package.json文件中 npm install --save-dev yarn add --dev 更新本地依赖包 npm update yarn upgrade 卸载本地依赖包 npm uninstall yarn remove 安装全局依赖包 npm install -g yarn global add 更新全局依赖包 npm update -g yarn global upgrade 查看全局依赖包 npm ls -g yarn global list 卸载全局依赖包 npm uninstall -g yarn global remove 1.2.4 常用工具3:npx和npm scripts 1.NPM自带的包执行器——npx npx是什么?可能很多Node***对这个小工具并没有太多关注。npx是NPM自带的一个包执行器。npx要解决的主要问题是调用项目内部安装的模块。就像NPM极大地提升了安装和管理包依赖的体验,在NPM的基础之上,npx让NPM包中的命令行工具和其他可执行文件在使用上变得更加简单。 由于安装NPM时已经自带npx,因此只需要验证当前的npx版本即可,具体命令如下: npx --version 6.13.4 下面以测试工具Mocha(https://mochajs.org/)为例,介绍npx的用法。 在本地安装Mocha依赖包,命令如下: npm install mocha 使用如下方式执行Mocha命令: ./node_modules/.bin/mocha --version 7.0.1 此时可以使用npx代替上述方式: npx mocha --version 7.0.1 %提示:除了上述命令,npx还有许多有用的特性,读者可以自行参考官方文档,网址为https://github.com/npm/npx。 2.npm scripts简介 NPM还有一个常用的命令工具,即npm scripts。 npm scripts是指在package.json文件中使用scripts字段定义的脚本命令,例如: 01 { 02 "scripts": { 03 "start": "node ./bin/www" 04 } 05 } 此时如果想要运行项目,可以直接执行以下命令: npm run start 同时,start作为一个常用命令,还支持如下简写: npm start npm scripts的用法还包括: l 项目的相关脚本,可以集中在一个地方。 l 不同项目的脚本命令,只要功能相同,就可以使用相同的npm scripts。例如,启动项目统一使用npm run start命令。 l 此外,还可以利用NPM提供的很多辅助功能。对于NPM的辅助功能,这里以npm scripts的钩子功能为例进行介绍。 npm scripts有pre和post两个钩子,如start脚本命令的钩子是prestart和poststart。当执行npm run start时,会自动按照下面的顺序执行: npm run prestart && npm run start && npm run poststart 因此,可以在这两个钩子中完成一些前置工作和后续工作,例如: 01 { 02 "scripts": { 03 "prestart": "npm run build", 04 "start": "node ./bin/www", 05 "poststart": "echo node server started" 06 } 07 } 除此之外,NPM默认还提供下面这些钩子: prepublish,postpublish preinstall,postinstall preuninstall,postuninstall preversion,postversion pretest,posttest prestop,poststop prestart,poststart prerestart,postrestart %提示:npm scripts除了上述介绍的功能之外,还有许多有用的特性,读者可以自行参考官方文档,网址为https://docs.npmjs.com/misc/scripts。 1.2.5 **个Node.js示例 前面已经将Node开发环境搭建完成,接下来可以开发**个Node示例。 (1)新建JavaScript文件并命名为HelloWorld.js,代码如下: 01 var http = require("http"); 其中,通过require()引入了Node内置的HTTP模块。 (2)通过http.createServer()方法创建一个HTTP服务,代码如下: 01 var http = require("http"); 02 03 var server = http.createServer((request, response) => { 04 response.end(); 05 }) 06 server.listen(8000); (3)接收请求并响应请求,修改代码如下: 01 var http = require("http"); 02 03 var server = http.createServer((request, response) => { 04 // 发送HTTP头部 05 // HTTP 状态值:200 : OK 06 // 内容类型:text/plain 07 response.writeHead(200, { 'Content-Type': 'text/plain' }); 08 09 // 请求的响应数据 10 response.end('Hello World'); 11 }) 12 server.listen(8000); // 监听8000端口 13 14 console.log('Server running at http://127.0.0.1:8000/') (4)启动Node服务,命令如下: node HelloWorld.js Node服务启动成功,命令窗口输出结果如下: Server running at http://127.0.0.1:8000/ (5)此时,使用浏览器访问http://127.0.0.1:8000/,页面显示Hello World,如图1.4所示。 图1.4 **个Node示例 以上便是基于Node开发的**个示例。回顾这个示例,主要步骤如下: (1)通过required()引入模块。 (2)创建HTTP服务,并监听指定的端口。 (3)接收请求并响应请求。 1.3 搭建React环境 1.2节介绍了Node环境的搭建,并编写了**个基于Node的HTTP服务。本节将介绍React环境的搭建,同时会通过React和Node结合开发一个完整的例子,让读者对二者有一个大概的认识。 1.3.1 安装React 安装React有以下两种方式: l 使用CDN链接; l 使用create-react-app工具。 1.使用CDN链接 React官方提供的CDN链接如下: <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"> </script> 需要注意的是,上述CDN链接只适用于开发环境,不适用于生产环境。生产环境中,需要使用压缩等优化处理后的依赖包,以节约带宽,提**率,其链接如下: <script src="https://unpkg.com/react@16/umd/react.production.min.js"> </script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"> </script> 小知识:CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过**平台的负载均衡、内容分发和调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问的响应速度和命中率。 成功引入React的相关依赖包后,下面通过一个例子来了解React的用法。 (1)新建HTML文件并命名为react_example.html,编写代码如下: 01 <!DOCTYPE html> 02 <html lang="en"> 03 04 <head> 05 <meta charset="UTF-8"> 06 <title>React Example</title> 07 <script src="https://unpkg.com/react@16/umd/react.development.js"> </script> 08 <script src="https://unpkg.com/react-dom@16/umd/react-dom. development.js"></script> 09 </head> 10 11 <body> 12 <div id="app"></div> 13 </body> 14 <script> 15 const e = React.createElement( 16 'h1', 17 null, 18 'Hello React!' 19 ) 20 ReactDOM.render( 21 e, 22 document.getElementById('app') 23 ) 24 </script> 25 26 </html> (2)使用浏览器打开上述HTML文件,可以看到如图1.5所示的效果。 图1.5 使用CDN链接 (3)上述代码中使用的是React的原生写法,为了简化编码,React还提供了一种叫作JSX(JavaScript XML)的写法。想要在React中使用JSX,需要引入Babel的依赖包,命令如下: <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> %提示:第2章会对JSX做详细介绍。 (4)为<script>标签添加type="text/babel"属性。 (5)使用React JSX语法进行编码,具体代码如下: 01 <!DOCTYPE html> 02 <html lang="en"> 03 04 <head> 05 <meta charset="UTF-8"> 06 <title>React Example</title> 07 <script src="https://unpkg.com/react@16/umd/react.development.js"> </script> 08 <script src="https://unpkg.com/react-dom@16/umd/react-dom. development.js"></script> 09 <script src="https://unpkg.com/babel-standalone@6/babel.min.js"> </script> 10 </head> 11 12 <body> 13 <div id="app"></div> 14 </body> 15 <script type="text/babel"> 16 ReactDOM.render( 17 <h1>Hello React!</h1>, 18 document.getElementById('app') 19 ) 20 </script> 21 22 </html> 2.使用create-react-app工具 create-react-app是React团队**的工具,通过该工具无须任何配置就能快速构建React开发环境。它在内部使用Babel和Webpack,但读者无须了解它们的任何细节。要使用该工具,需要确保已安装的Node版本是8.10以上,npm版本是5.6以上。 %提示:第4章会对Webpack做详细介绍。 (1)全局安装create-react-app工具,命令如下: npm install -g create-react-app (2)使用create-react-app工具创建项目,命令如下: create-react-app first-app cd first-app (3)使用如下npm scripts运行该项目: npm start // 或者 yarn start 此时,服务启动后会在浏览器中自动打开http://localhost:3000,效果如图1.6所示。 图1.6 使用create-react-app工具的效果展示 1.3.2 **个React示例 1.3.1节介绍了React的两种安装方式。本节将基于create-react-app工具来开发一个待办事项的应用程序(下面称为TodoList App),通过这个例子来了解React开发的全过程。 这个待办事项的应用程序主要具有以下功能: l 查看待办事项; l 添加待办事项; l 删除待办事项; l 修改待办事项状态。 1.TodoList App 1.0版本 具体操作步骤如下: (1)通过create-react-app工具新建初始项目,命令如下: create-react-app todo-list cd todo-list npm start // 或者用yarn start (2)此时浏览器会自动打开http://localhost:3000。至此,新建项目成功。 (3)修改项目中的文件./src/App.js,完整代码如下: 01 import React from 'react'; 02 03 export default class App extends React.Component { 04 constructor(props) { 05 super(props); 06 } 07 08 render() { 09 return ( 10 <div> 11 <h1>My First React App -- todo-list</h1> 12 </div> 13 ); 14 } 15 } (4)此时会自动刷新浏览器页面,效果如图1.7所示。 图1.7 TodoList初始化效果 %提示:当更新项目代码时,浏览器自动刷新是依赖Webpack实现的。第4章会对Webpack进行介绍。 项目初始化完成后,要进行具体的代码编写。 (5)实现待办事项列表的显示。修改./src/App.js文件的代码如下: 01 import React from 'react'; 02 03 export default class App extends React.Component { 04 constructor(props) { 05 super(props); 06 this.state = { 07 todoItems: [ 08 { id: 0, value: 'React', done: false, delete: false } 09 ] 10 } 11 } 12 13 render() { 14 return ( 15 <div> 16 <h1>TodoList</h1> 17 <div> 18 <input type="text" placeholder="add something..." /> 19 <button type="submit">添加</button> 20 </div> 21 <ul> 22 { 23 this.state.todoItems.map((item) => { 24 if (item.delete) return; 25 return ( 26 <li key={item.id}> 27 <label>{item.value}</label> 28 <button>删除</button> 29 </li> 30 ) 31 }) 32 } 33 </ul> 34 </div> 35 ); 36 } 37 } 此时,浏览器自动刷新页面,效果如图1.8所示。 图1.8 TodoList App列表效果 (6)实现添加和删除待办事项等相关功能。修改./src/App.js文件的代码如下: 01 import React from 'react'; 02 03 export default class App extends React.Component { 04 // 省略了未修改的代码 05 06 addTodoItem = () => { 07 const newTodoItem = { 08 id: this.state.todoItems.length, 09 value: this.refs.todoItemValue.value, 10 done: false, 11 delete: false 12 }; 13 this.setState({ 14 todoItems: [...this.state.todoItems, newTodoItem] 15 }) 16 } 17 18 deleteTodoItem = (item) => { 19 item.delete = true; 20 this.setState({ 21 todoItems: [...this.state.todoItems, item] 22 }) 23 } 24 25 render() { 26 return ( 27 <div> 28 <h1>TodoList</h1> 29 <div> 30 <input 31 type="text" 32 ref="todoItemValue" 33 placeholder="add something..." 34 /> 35 <button 36 type="submit" 37 onClick={this.addTodoItem} 38 > 39 添加 40 </button> 41 </div> 42 <ul> 43 { 44 this.state.todoItems.map((item) => { 45 if (item.delete) return; 46 return ( 47 <li key={item.id}> 48 <label>{item.value}</label> 49 <button 50 onClick={() => this.deleteTodoItem (item)} 51 > 52 删除 53 </button> 54 </li> 55 ) 56 }) 57 } 58 </ul> 59 </div> 60 ); 61 } 62 } (7)修改待办事项状态与删除待办事项的写法类似,这里不再赘述,留给读者自行练习。 至此,一个简单的TodoList App就完成了。 虽然TodoList App的功能已基本实现,但写法却并不“优雅”,没有用到React组件等特性,而可重复使用组件正是React的优势所在。 2.TodoList App 2.0版本 下面将通过封装组件的方式对现有的TodoList App进行优化。 通过对TodoList App现有功能进行分析,大概可以将其分成以下几个组件。 l TodoForm:待办事项表单,包括输入框和添加功能; l TodoList:待办事项列表; l TodoListItem:待办事项列表中的具体内容及相关操作。 具体实现步骤如下: (1)新建文件并命名为./src/TodoForm.js,编写代码如下: 01 import React from 'react'; 02 03 export default class TodoForm extends React.Component { 04 addTodoItem = () => { 05 this.props.addTodoItem(this.refs.todoItemValue.value); 06 } 07 08 render() { 09 return ( 10 <div> 11 <input 12 type="text" 13 ref="todoItemValue" 14 placeholder="add or search something..." 15 /> 16 <button type="submit" onClick={this.addTodoItem}>添加 </button> 17 </div> 18 ) 19 } 20 } (2)修改./src/App.js的逻辑和代码如下: 01 import React from 'react'; 02 import TodoForm from './TodoForm'; 03 04 export default class App extends React.Component { 05 // 省略了未修改的代码 06 07 addTodoItem = (todoItemValue) => { 08 const newTodoItem = { 09 id: this.state.todoItems.length, 10 value: todoItemValue, 11 done: false, 12 delete: false 13 }; 14 this.setState({ 15 todoItems: [...this.state.todoItems, newTodoItem] 16 }) 17 } 18 19 // 省略了未修改的代码 20 21 render() { 22 return ( 23 <div> 24 <h1>TodoList</h1> 25 <TodoForm 26 addTodoItem={this.addTodoItem} 27 /> 28 // 省略了未修改的代码 29 </div> 30 ); 31 } 32 } %提示:上述例子中用到了数据流等相关知识,如State和Props等,会在第2章中详细介绍。 (3)按照TodoForm组件的思路实现TodoListItem组件,即新建./src/TodoListItem.js文件,代码如下: 01 import React from 'react'; 02 03 export default class TodoListItem extends React.Component { 04 deleteTodoItem = () => { 05 this.props.deleteTodoItem(this.props.item); 06 } 07 08 render() { 09 return ( 10 <li> 11 <label>{this.props.item.value}</label> 12 <button 13 onClick={this.deleteTodoItem} 14 > 15 删除 16 </button> 17 </li> 18 ) 19 } 20 } (4)实现TodoList组件,即新建./src/TodoList.js文件,代码如下: 01 import React from 'react'; 02 import TodoListItem from './TodoListItem'; 03 04 export default class TodoList extends React.Component { 05 deleteTodoItem = (item) => { 06 this.props.deleteTodoItem(item); 07 } 08 09 render() { 10 return ( 11 <ul> 12 { 13 this.props.todoItems.map((item) => { 14 if (item.delete) return; 15 return ( 16 <TodoListItem 17 key={item.id} 18 item={item} 19 deleteTodoItem={this.deleteTodoItem} 20 /> 21 ) 22 }) 23 } 24 </ul> 25 ) 26 } 27 } (5)修改./src/App.js的逻辑和代码如下: 01 import React from 'react'; 02 import TodoForm from './TodoForm'; 03 import TodoList from './TodoList'; 04 05 export default class App extends React.Component { 06 // 省略了未修改的代码 07 08 render() { 09 return ( 10 <div> 11 <h1>TodoList</h1> 12 <TodoForm 13 addTodoItem={this.addTodoItem} 14 /> 15 <TodoList 16 todoItems={this.state.todoItems} 17 deleteTodoItem={this.deleteTodoItem} 18 /> 19 </div> 20 ); 21 } 22 } 此时,组件化封装优化后的TodoList App基本完成,效果如图1.9所示。 图1.9 TodoList App 2.0版本界面 至此,相信读者不仅了解了React开发的相关知识,也对React的组件化思想有了初步的认识。 1.3.3 **个React Node.js组合示例 1.3.2节中实现的TodoList App,数据来源是由前端定义的,通常Web应用的数据都是存储在服务端的数据库中。前端通过基于HTTP的接口来完成数据的增、删、改、查等操作。 1.服务端(Node端) 下面基于前面学习的Node开发知识来构建TodoList App的服务端程序。 (1)新建一个Node项目,命令如下: mkdir todo-list-server cd todo-list-server (2)使用npm init命令初始化Node项目生成package.json文件。项目初始化时会提示输入若干项,可以按Enter键接受默认值。如果想跳过提示直接生成package.json文件,还可以使用如下命令: npm init -y (3)为了简化服务端的实现代码,还需要安装Express依赖包,命令如下: npm install --save express %提示:Express是一个保持*简化规模且灵活的Node Web应用程序框架,它为Web和移动应用程序提供了强大的功能。关于Express框架的使用,第5章会详细介绍。 (4)新建Node项目主文件app.js,并添加代码如下: 01 var express = require('express'); 02 var app = express(); 03 04 app.get('/', function (req, res) { 05 res.send('Hello World!'); 06 }); 07 08 app.listen(8000, function () { 09 console.log('Server running at http://127.0.0.1:8000/') 10 }); (5)启动Node服务,命令如下: node app.js Server running at http://127.0.0.1:8000/ 此时,打开浏览器访问http://localhost:8000,页面上出现“Hello World!”,项目初始化完成。 2.服务端接口 下面在服务端程序的基础上开发待办事项的增、删、改、查接口。 为了简化接口和实现步骤,这里将服务端的数据直接编写在代码中,而不使用数据库存储。修改todo-list-server中的app.js代码如下: 01 var express = require('express'); 02 var app = express(); 03 04 var todoItems = [ 05 { id: 0, value: 'React', done: false, delete: false } 06 ] 07 08 app.get('/items', function (req, res) { 09 res.send(todoItems); 10 }); 11 12 app.listen(8000, function () { 13 console.log('Server running at http://127.0.0.1:8000/') 14 }); 此时,在浏览器中打开http://localhost:8000/items,会返回如图1.10所示的结果。 图1.10 获取待办事项接口 3.前端 完成接口之后,还需要修改前端(React端)逻辑,调用该接口获取待办事项的数据。 (1)基于上一节React前端,创建前端项目如下: cp -R todo-list todo-list-client cd todo-list-client npm install (2)使用包管理器引入一个基于Promise的HTTP库——axios(https://github.com/axios/ axios),它可以运行在浏览器和Node环境中,使***可以很容易地发送HTTP请求。具体引入命令如下: npm install --save axios (3)修改todo-list-client项目中的./src/App.js文件代码如下: 01 import React from 'react'; 02 import axios from 'axios'; 03 import TodoForm from './TodoForm'; 04 import TodoList from './TodoList'; 05 06 export default class App extends React.Component { 07 constructor(props) { 08 super(props); 09 this.state = { 10 todoItems: [] 11 } 12 } 13 14 componentDidMount() { 15 const that = this; 16 axios.get('http://localhost:8000/items') 17 .then(function (response) { 18 that.setState({ 19 todoItems: [...response.data] 20 }) 21 }) 22 } 23 24 // 省略了未修改的代码 25 } 此时,运行todo-list-client项目会发现浏览器报错,报错信息如图1.11所示。 图1.11 浏览器报错信息 这是因为浏览器跨域限制,解决方法是在todo-list-server项目中的app.js文件中添加以下代码: 01 // 省略了未修改的代码 02 03 app.all('*', function (req, res, next) { 04 // 允许跨域的域名,*代表允许任意域名跨域 05 res.header('Access-Control-Allow-Origin', '*'); 06 // 允许跨域的请求头 07 res.header('Access-Control-Allow-Headers', 'content-type'); 08 // 允许跨域的请求方法 09 res.header('Access-Control-Allow-Methods', 'DELETE,PUT,POST,GET, OPTIONS'); 10 next(); 11 }) 12 13 app.get('/items', function (req, res) { 14 res.send(todoItems); 15 }); 16 17 // 省略了未修改的代码 (4)重新运行Node服务后刷新浏览器,发现错误已解决并且成功获取到待办事项的数据。 %提示:关于跨域限制问题,将在第7章中详细介绍。 (5)完成了查询接口后,新增、删除和修改待办事项就很容易理解了。需要注意的是: l 新增接口为POST请求; l 删除接口为DELETE请求; l 修改接口为PATCH请求。 %提示:上述接口规范属于RESTful架构风格,将在第3章中详细介绍。 修改todo-list-server项目中的app.js文件的代码如下: 01 // 省略了未修改的代码 02 03 app.get('/items', function (req, res) { 04 res.send(todoItems); 05 }); 06 07 app.post('/items', function (req, res) { 08 if (req.body.todoItem) { 09 todoItems = [...todoItems, req.body.todoItem] 10 } 11 res.send(todoItems); 12 }) 13 14 app.delete('/items', function (req, res) { 15 if (req.body.id) { 16 todoItems.forEach(todoItem => { 17 if (todoItem.id === req.body.id) { 18 todoItem.delete = true; 19 } 20 }) 21 } 22 res.send(todoItems); 23 }) 24 25 // 省略了未修改的代码 其中,POST和DELETE请求的数据都在请求体中,所以需要通过req.body获取请求传递的内容。 %提示:关于HTTP的请求头和请求体,将在第3章中详细介绍。 修改todo-list-client项目中的./src/App.js文件以调用上述接口,代码如下: 01 addTodoItem = (todoItemValue) => { 02 const newTodoItem = { 03 id: this.state.todoItems.length, 04 value: todoItemValue, 05 done: false, 06 delete: false 07 }; 08 const that = this; 09 axios.post('http://localhost:3000/item-add', { 10 todoItem: newTodoItem 11 }) 12 .then(function (response) { 13 that.setState({ 14 todoItems: [...response.data] 15 }) 16 }) 17 } 18 19 deleteTodoItem = (item) => { 20 const that = this; 21 axios.delete('http://localhost:3000/item-delete', { 22 data: { 23 id: item.id 24 } 25 }) 26 .then(function (response) { 27 that.setState({ 28 todoItems: [...response.data] 29 }) 30 }) 31 } (6)重新运行Node服务,但是接口并没有如预期那样生效。通过在todo-list-server项目的app.js文件中做调试打印发现,req.body.*为未定义,那么,该如何解决呢? 这是因为需要通过依赖包body-parser来完成请求体的解析。解决方法是首先在todo- list-server项目中运行以下命令: npm install --save body-parser 然后在todo-list-server项目的app.js文件中添加以下代码: 01 var express = require('express'); 02 var bodyParser = require('body-parser'); 03 var app = express(); 04 05 app.use(bodyParser.json()); 06 07 var todoItems = [ 08 { id: 0, value: 'React', done: false, delete: false } 09 ] 10 11 // 省略了未修改的代码 依赖包body-parser的作用就是对POST和DELETE请求的请求体进行解析。 (7)再次运行Node服务,然后刷新浏览器,即可进行新增和删除操作。 另外,修改待办事项与新增、删除待办事项的写法类似,可参考前面的React示例,这里不再赘述,留给读者自行练习。
    目录
    第1篇 React和Node.js基础 第1章 准备:搭建React Node.js开发环境 2 1.1 为什么选择React Node.js 2 1.1.1 React的优势 2 1.1.2 Node.js的优势 3 1.1.3 React Node.js组合的优势 3 1.2 搭建Node.js环境 4 1.2.1 安装Node.js 4 1.2.2 常用工具1:NPM、CNPM和NRM 8 1.2.3 常用工具2:YARN 9 1.2.4 常用工具3:npx和npm scripts 10 1.2.5 **个Node.js示例 12 1.3 搭建React环境 13 1.3.1 安装React 13 1.3.2 **个React示例 16 1.3.3 **个React Node.js组合示例 23 1.4 React Node.js开发工具 28 1.4.1 Visual Studio Code简介 28 1.4.2 Chrome简介 31 1.4.3 Postman简介 34 1.5 小结 38 第2章 前端开发:React技术从0到1 39 2.1 JSX简介 39 2.1.1 JSX的由来 39 2.1.2 JSX语法 40 2.2 组件 46 2.2.1 组件的定义 46 2.2.2 高阶组件 48 2.3 数据流 51 2.3.1 Props与State简介 51 2.3.2 组件通信简介 56 2.3.3 Context API简介 58 2.3.4 Redux简介 62 2.3.5 MobX简介 72 2.4 生命周期 75 2.4.1 挂载和卸载 75 2.4.2 状态更新 76 2.5 小结 77 第3章 后端开发:Node.js技术从0到1 79 3.1 Node.js的特性 79 3.1.1 模块化规范 80 3.1.2 异步I/O和事件驱动 83 3.2 HTTP简介 86 3.2.1 请求和响应 87 3.2.2 RESTful架构风格 90 3.2.3 JSON数据格式 93 3.3 开始使用Node.js 95 3.3.1 hello world示例 95 3.3.2 回调函数与Promise对象 97 3.3.3 调试工具 100 3.4 Node.js的常用模块 104 3.4.1 全局变量 104 3.4.2 工具模块 108 3.4.3 HTTP模块 111 3.4.4 事件循环和EventEmitter 114 3.5 小结 117 第2篇 打包部署和项目开发实战 第4章 构建与部署 120 4.1 Webpack简介 120 4.1.1 一切皆模块 121 4.1.2 Webpack的使用 124 4.1.3 Webpack环境配置 130 4.1.4 Webpack进阶 134 4.2 Nginx简介 138 4.2.1 Nginx的基本特性 140 4.2.2 Nginx的安装 144 4.2.3 Nginx的配置 146 4.2.4 Nginx的**特性 150 4.3 PM2简介 153 4.3.1 守护进程 154 4.3.2 进程管理工具对比 154 4.3.3 PM2的安装和使用 154 4.4 部署 158 4.4.1 React的部署 159 4.4.2 Node.js的部署 160 4.5 小结 161 第5章 项目实战1:React Node.js实现单页面评论系统 162 5.1 研发流程 162 5.2 产品原型 163 5.2.1 文章列表页 163 5.2.2 文章详情与评论页 164 5.2.3 文章编辑页 165 5.3 技术选型 165 5.3.1 前端技术 165 5.3.2 后端技术 168 5.4 项目开发 175 5.4.1 文章列表 175 5.4.2 文章详情与评论 184 5.4.3 文章编辑 189 5.5 测试部署 193 5.5.1 接口测试 193 5.5.2 项目部署 195 5.6 小结 197 第3篇 React和Node.js进阶 第6章 React进阶 200 6.1 虚拟DOM 200 6.2 Diff算法 202 6.2.1 Tree Diff简介 203 6.2.2 Component Diff简介 204 6.2.3 Element Diff简介 204 6.3 Fiber机制 205 6.3.1 Fiber树 207 6.3.2 Reconciliation阶段 207 6.3.3 Commit阶段 209 6.3.4 React Fiber小结 209 6.4 Immutable.js库 210 6.4.1 浅拷贝 210 6.4.2 深拷贝 211 6.4.3 Immutable.js简介 212 6.5 Hook特性 217 6.5.1 State Hook简介 217 6.5.2 Effect Hook简介 218 6.5.3 自定义Hook 221 6.5.4 其他Hook 223 6.6 小结 224 第7章 Node.js进阶 225 7.1 跨域 225 7.1.1 同源策略 225 7.1.2 跨域方案 227 7.2 鉴权 231 7.2.1 Session机制 232 7.2.2 JWT标准 235 7.3 缓存 238 7.3.1 Redis方案 239 7.3.2 单点登录 244 7.4 对象—关系映射 246 7.4.1 Sequelize——关系型数据库的ORM实现 247 7.4.2 Mongoose——MongoDB的ORM实现 255 7.5 小结 259 第8章 项目实战2:React Node.js实现社区项目从开发到上线 261 8.1 产品原型 261 8.1.1 注册与登录 261 8.1.2 新建主题 262 8.1.3 主题列表 262 8.1.4 主题详情 262 8.1.5 评论功能 263 8.2 技术选型 263 8.2.1 服务器端 264 8.2.2 Web前端 268 8.3 项目开发 273 8.3.1 注册与登录 273 8.3.2 新建主题 289 8.3.3 主题列表 293 8.3.4 主题详情 297 8.3.5 评论功能 300 8.4 项目部署与测试 304 8.4.1 项目部署 305 8.4.2 E2E测试 306 8.5 小结 309 第4篇 项目优化和服务端渲染 第9章 项目优化 312 9.1 浏览器缓存 312 9.1.1 强缓存 313 9.1.2 协商缓存 314 9.1.3 缓存位置 315 9.1.4 缓存策略 317 9.1.5 缓存示例 317 9.2 压缩 321 9.2.1 UglifyJS工具集 321 9.2.2 gzip压缩 323 9.3 懒加载 325 9.3.1 组件懒加载 325 9.3.2 路由懒加载 326 9.4 按需引入 327 9.4.1 Tree Shaking——垃圾代码净化 327 9.4.2 部分引入 329 9.5 负载均衡 330 9.5.1 负载均衡分类 330 9.5.2 负载均衡工具 331 9.5.3 负载均衡实现 332 9.6 CDN简介 333 9.6.1 工作过程 333 9.6.2 系统组成 334 9.7 小结 335 第10章 服务端渲染 336 10.1 服务端渲染简介 336 10.1.1 客户端渲染示例 336 10.1.2 服务端渲染示例 339 10.1.3 客户端渲染和服务端渲染的优缺点 340 10.2 React服务端渲染 341 10.2.1 组件 342 10.2.2 同构 347 10.2.3 路由 351 10.2.4 状态 355 10.3 Next.js服务端渲染 357 10.3.1 Next.js简介 357 10.3.2 Next.js开发 358 10.4 SEO——搜索引擎优化 361 10.4.1 React Helmet组件 361 10.4.2 预渲染 363 10.5 小结 364

    与描述相符

    100

    北京 天津 河北 山西 内蒙古 辽宁 吉林 黑龙江 上海 江苏 浙江 安徽 福建 江西 山东 河南 湖北 湖南 广东 广西 海南 重庆 四川 贵州 云南 西藏 陕西 甘肃 青海 宁夏 新疆 台湾 香港 澳门 海外