《深入浅出React和Redux》(1) - React基础

2023-10-31

create-react-app

React技术依赖的技术栈比较多,比如,转译JavaScript代码需要使用Babel,模块打包工具要使用Webpack,定制build过程需要grunt或者gulp。create-react-app命令可以免去配置这些技术栈的麻烦,自动生成一个基本的react-app模版项目,让开发者可以基于这个模版快速开始React应用的开发。
首先要安装create-react-app命令:

npm install --global create-react-app

然后就可以创建了:

create-react-app <app-name>

组件

React的首要思想是通过组件(Component)来开发应用。所谓组件,简单说,指的是能完成某个特定功能的独立的、可重用的代码。这与传统的web开发方式差异很大,以前用HTML来代表内容,用CSS代表样式,用JavaScript来定义交互行为,这三种语言分在三种不同的文件里面,实际上是把不同技术分开管理了,而不是逻辑上的“分而治之”。组件则是按照逻辑(功能)来组织的。

Component作为所有组件的基类,提供了很多组件共有的功能

JSX

JSX, 是JavaScript的语法扩展(eXtension),允许在JavaScript中可以编写像HTML一样的代码。在JSX中使用的“元素”不局限于HTML中的元素,可以是任何一个React组件,React判断一个元素是HTML元素还是React组件的原则就是看第一个字母是否大写。

React的理念

React的理念可以归结为一个简单的公式:

UI = render(data)

即render函数,与它接收的data决定了UI渲染的结果。render是一个纯函数,它的输出完全依赖输入。
对于开发者来说,重要的是区分开哪些属于data,哪些属于render,想要更新用户界面,要做的就是更新data,用户界面自然会做出响应。所以React实践的也是“响应式编程”(ReactiveProgramming)的思想,这也就是React为什么叫做React的原因。

但在数据发生变化时,React并不会重新渲染整个页面,它利用Virtual DOM实现了只渲染差异DOM的特性,渲染效率很高。

Virtual DOM

要了解Virtual DOM,就要先了解DOM,DOM是结构化文本的抽象表达形式,这里所谓的结构化文本即HTML文本,HTML中的每个元素都对应DOM中某个节点,HTML元素的层级关系对应DOM树。

浏览器在渲染HTML的时候,会先将HTML文本解析以构建DOM树,然后再根据DOM树渲染UI,当要改变界面内容的时候,可以通过对DOM进行操作来实现。

Web前端开发关于性能优化有一个原则:尽量减少DOM操作。因为DOM操作会引起浏览器对网页的重新绘制,这是一个相对耗时的过程。

然后Virtual DOM就是对DOM的更高一层的抽象,当React组件发生变化时,React新旧Virtual DOM之间的差异,再根据这些差异来操作真正的DOM。

React利用函数式编程的思想以及数据驱动的模式进行Web页面的开发,数据的变化触发的只是Virtual DOM的变化,剩下的部分由React去完成,开发者并不需要关心。

在开发React应用的时候,开发者使用的是声明式的语法,专注于描述操作的结果,而不用过多考虑操作的细节。

易于维护组件的设计要素

设计组件的时候,应该尽量保持一个组件只做一件事。

如果发现一个组件功能太多代码量太大的时候,就可以考虑将其拆分了;但拆分组件时要注意,组件的粒度过粗、过细都不好,这就同“一个组件只做一件事”一样要看具体的场景。

拆分组件时,最重要也最困难的是要确定组件的边界,每个组件都应该是可以独立存在的,如果两个组件逻辑太紧密,无法清晰定义各自的责任,那也许这两个组件本身就不该被拆开,作为同一个组件也许更合理。

通用的软件设计原则也适用于组件的设计:组件应该遵循高内聚、低耦合的原则。

prop和state

React组件的数据分为两种,prop和state,无论prop或者state的改变,都可能引发组件的重新渲染。prop是组件的对外接口,state用于存储组件的内部状态。

prop

一个React组件通过定义自己能够接受的prop就定义了自己的对外公共接口。props的类型可以是任何一种JavaScript语言支持的数据类型,包括函数。
当prop的类型不是字符串类型时,在JSX中必须用花括号{}把prop值包住。
React组件不能修改传入的prop的值。

propTypes用于定于组件的接口规范:
首先倒入PropTypes

import PropTypes from 'prop-types';

在[classname].propTypes中添加对props的限制,比如下面的代码限制caption字段为string类型,而且isRequired必须传值。

Counter.propTypes = {
  caption: PropTypes.string.isRequired
}

这些添加的限制,会被用于运行时和静态代码检查,据此来判断组件是否被正确地使用。
但这种限制并不是强制的,即使被违反,组件仍能正常工作,但会在浏览器的console里抛出警告信息。

propTypes可以帮助在开发阶段尽早发现代码中的问题,但是最好不要带到产品环境中,babel-react-optimize可以在发布产品代码时自动移除定义的propTypes。

defaultProps可以用来为props中的字段定义缺省值:

Counter.defaultProps = {
  initValue: 3
};

state

state用来记录组件自身数据的变化。
state的初始化要在组件的构造函数中进行,通过为this.state赋值就完成了其初始化:

this.state = {
  count: props.initValue
};

组件的state必须是一个JS对象,即使组件需要的只是一个数字类型的字段,也必须把它作state的一个字段。

通过this.state可以读取其中的值,比如this.state.count.

修改state的值必须通过this.setState()方法进行:

this.setState({ count: this.state.count + 1 });

直接修改并不会生效,这是因为setState除了会修改state的值外,还会触发页面的重新渲染。

组件的生命周期

在一个React组件的生命周期中,会经历三个过程:

  • 装载过程(Mount),也就是把组件第一次在DOM树中渲染的过程;
  • 更新过程(Update),当组件被重新渲染的过程;
  • 卸载过程(Unmount),组件从DOM中删除的过程。

装载过程

组件第一次被渲染时,主要会调用如下函数:

  • constructor
  • render
  • componentDidMount
constructor

并不是每个组件都需要定义自己的构造函数,在下面的情况下,组件才需要定义构造函数:

  • 初始化state,如果组件包含state,就需要在构造函数初始化;
  • 绑定成员函数的this环境
render

一个React组件可以忽略其他所有函数都不实现,但是一定要实现render函数,因为父类React.Component类对除render之外的生命周期函数都有默认实现。
render函数并不做实际的渲染动作,它只是返回一个JSX描述的结构,最终由React来进行渲染。
render函数应该是一个纯函数,完全根据this.state和this.props来决定返回的结果,而且不要产生任何副作用。

componentDidMount

React在根据render返回的结果来渲染页面的时候,componentDidMount会被触发,但它并不在render执行后立即触发,要等React库根据所有组件的render都执行完。

更新过程

更新过程主要会调用如下函数:

  • shouldComponentUpdate
  • render
  • componentDidUpdate
shouldComponentUpdate

shouldComponentUpdate也是一个非常重要的函数,它的返回值是bool,决定是否应该重新渲染组件。
需要优化性能时,可以定制shouldComponentUpdate。父类React.Component中的默认实现方式是始终返回true。定制时可以对比state与props,只有变化时才更新。

卸载过程

卸载过程只涉及一个函数componentWillUnmount,当React组件要从DOM树上删除掉之前,对应的componentWillUnmount函数会被调用,所以这个函数适合做一些清理性的工作。
比如在componentDidMount中用非React的方法创造了一些DOM元素,如果撒手不管可能会造成内存泄露,那就需要在componentWillUnmount中把这些创造的DOM元素清理掉。

组件向外传递数据

通过prop可以从父组件传递数据给子组件,很多时候也需要将数据从子组件返回给父组件,这时仍然可以利用prop来实现。
prop支持任何类型的JavaScript对象,包括函数,函数可以像其他对象一样作为prop的值从父组件传递给子组件,又可以被子组件作为函数调用,于是可以借助函数将数据从子组件返回给父组件。

但这种传递方式在涉及到多个、多层组件之间的数据传递时就比较复杂了,多层组件的数据需要层层传递,平级组件之间的数据又需要依赖父组件的中转,可能导致数据冗余、数据流混乱。接下来看看redux是如何解决这类问题的。

参考书籍

《深入浅出React和Redux》 程墨

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《深入浅出React和Redux》(1) - React基础 的相关文章

  • 为什么 i&1 可以判断奇偶

    记录一下看到过几次但是总会遗忘的知识点 是位运算 在计算机里是只认识二进制的 我们人类用的一般是十进制 而二进制有个特点就是每一位上要么是0要么是1 还有一个特点是如果哪个位置是1 那一位的值就是2n 这个符号表示次方 n就是这个1所处的位
  • 吴恩达机器学习python代码练习三(多类别分类)

    import numpy as np import pandas as pd import matplotlib pyplot as plt import scipy io as sio from scipy optimize import

随机推荐

  • 使用ddt实现unittest的参数化测试

    0 前言 本文介绍如何使用ddt库来完成unitest的参数化设置 ddt的github地址 ddt的官方文档 1 为什么需要参数化 我们在写单测中 需要考虑到各种场景 通过输入各种场景的值执行目的的方法 来判断输出是否是我们所期待的值 如
  • Android 中WebView的使用详解

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 前言 通过WebView控件可以实现加载网页的效果 加载URL 网络或者本地assets文件夹下的html文件 加载html代码 Nat
  • 测开学习技能清单

    一 代码语言 打好语言基础 python java 底层语言主要掌握java 更高级的语法可以选择python去学习 领域预演 DSL shell SQL Docker shell 是指一种应用程序 这个应用程序提供了一个界面 用户通过这个
  • 在Lumia 950 XL上运行Windows 10 ARM64,是种什么体验?

    本文于2019年02月01日首发于IT之家 地址 点击这里 2019年1月 据IT之家报道 微软Lumia 950 XL刷Windows 10 ARM64项目取得了巨大进展 显卡驱动已经成功运行 随后 适用于Lumia 950 XL的WiF
  • MYSQL 数据存在 (多条件同时满足)则更新,不存在则添加

    需求 提交数据时 数据不存在则添加 数据存在则更新 此处判断数据是否存在需要满足2个条件 cid date 如果两者同时满足的情况下 才更新数据 否则添加数据 表结构 使用的方法是 on duplicate key update INSER
  • 蓝桥杯 全球变暖 bfs学习

    全球变暖 你有一张某海域NxN像素的照片 表示海洋 表示陆地 如下所示 其中 上下左右 四个方向上连在一起的一片陆地组成一座岛屿 例如上图就有2座岛屿 由于全球变暖导致了海面上升 科学家预测未来几十年 岛屿边缘一个像素的范围会被海水淹没 具
  • 芜湖今年小升初计算机考试,刚刚!芜湖幼升小、小升初网上报名时间定了!附报名流程和具体安排...

    就在今天 芜湖发布了 关于做好2021年芜湖市义务教育网上报名审核工作的通知 其中明确幼升小和小升初的网上报名时间 家长们赶紧来看看 这则重要通知还说了哪些关于报名的重要信息吧 公办义务教育学校网上报名工作安排 民办义务教育学校网上报名工作
  • 使用torch以及tensorflow训练一个最简单网络的基本步骤

    torch import torch import torch nn functional as F import matplotlib pyplot as plt x torch Tensor unsqueeze torch Tensor
  • 本地域名解析hosts

    本地域名解析hosts 一 这个系统文件就是HOSTS文件 二 Hosts文件的基本内容和语法 三 Hosts文件的工作方式 问题 127 0 0 1 activate adobe com 这句话是什么意思 一 这个系统文件就是HOSTS文
  • conda环境中配置cuda+cudnn+pytorch深度学习环境

    本文参考 在conda虚拟环境中配置cuda cudnn pytorch深度学习环境 新手必看 简单可行 conda安装cudnn 江江ahh的博客 CSDN博客 一 创建虚拟环境 conda create n mytorch python
  • Connect函数第五个参数的作用

    第五个参数多线程才有意义 连接方式 默认 队列 直接 默认时 如果是多线程 默认使用队列方式 如果是单线程 默认使用直接方式 队列 槽函数所在的线程和信号接受者一样 直接 槽函数和所在线程和发送者一样
  • 使用mybatis无法向数据库中插入数据且后台无任何错误

    最近自己再搭建springboot mybatis的简单框架 但是一个insert功能纠结了我很长时间 头疼 insert不进去 那么检查点肯定是以下几种 后台是否报错 是否有异常抛出 没有 完全正常 还能返回到正常页面 无奈 mapper
  • C++中cout,cin,endl

    VC中头文件为 include
  • 常用的像素操作算法:图像加法、像素混合、提取图像中的ROI

    图像可以是看成是一个多维的数组 读取一张图片 可以看成是读入了一系列的像素内容 这些像素内容 按照不同的模式具有不同的格式 对于三通道的 RGB 位图来说 每个像素是一个 8 bit 整数的三元组 图像的像素操作是比较基础的图像算法 下面列
  • DATAX 数据同步 My SQL->Hive

    DATAX 数据同步 My SQL gt Hive 安装 DATAX官方地址 https github com alibaba DataX DATAX WEB官方地址 https github com WeiYe Jing datax we
  • 在嵌入式设备中不创建swap分区的原因何在

    我们知道 在linux中有一个很重要的概念 虚拟内存 当物理内存不够时 可以将内存中一些数据存储到硬盘上 而让出物理内存 我们一般在PC上安装linux时 会创建一个swap分区 其大小一般设置为内存的2倍 而我们在嵌入式设备中 却看不到该
  • 面试时,如何向HR解释自己频繁跳槽?

    有数据显示 现在的职场人 跳槽越来越频繁 95后平均7个月就离职 对于面试官来说 一个跳槽过于频繁的人总是存在潜在风险 比如抗压力差 稳定性不好 心不定这山望着那山高 职业规划不清晰等等 我一直强调一个观点 职场人跳槽 应该是为了下一步有更
  • git配置用户名和密码_IDEA配置码云教程

    第一步 先在电脑上安装git exe 否则以后会出现错误 官方下载地址 https www git scm com downloads 官方中文教程 https git scm com book zh v2 点击自动下载 然后下载好后 选择
  • linux几种压缩命令的简单使用

    在CentOS 7中 常用的解压缩命令是tar gzip和bzip2 压缩命令是tar gzip bzip2和zip 以下是这些命令的使用方法 1 tar命令 tar是常用的归档和压缩工具 可以用来打包 压缩和解压文件 常用的选项有 c 创
  • 《深入浅出React和Redux》(1) - React基础

    create react app React技术依赖的技术栈比较多 比如 转译JavaScript代码需要使用Babel 模块打包工具要使用Webpack 定制build过程需要grunt或者gulp create react app命令可