【React 进阶】props 和 state 的区别详解

2023-11-06

时隔一年半之久再次重新学习 React,好多都还是原来的样子,这次我要重新开启 React 的大门,希望各位小伙伴可以一起讨论学习呦~

前言

今天我们开始第一个专题:React 中 关于 props 和 state。当然我们不是对 props 和 state 基本用法的介绍,而是尝试由浅入深的来解释 props 和 state 的本质和区别,并且归纳使用它们时的注意事项。

我们在开发应用时,必然是要与数据进行频繁交互的。React 的核心思想是组件化的思想,所有的页面会被切分成一些独立的、可复用的组件。
那么数据从何而来呢?React 的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在 props 和 state 中。

UI = Component(props, state)

props 和 state 本质

props 是组件对外的接口,state 是组件对内的接口。 组件内可以引用其他组件,组件之间的引用形成了一个树状结构(组件树),如果下层组件需要使用上层组件的数据或方法,上层组件就可以通过下层组件的 props 属性进行传递,因此 props 是组件对外的接口。组件除了使用上层组件传递的数据外,自身也可能需要维护管理数据,这就是组件对内的接口 state。根据对外接口 props 和对内接口 state,组件计算出对应界面的UI。


props

组件从概念上看其实就是一个函数,它可以接受一个 props 作为输入值,所以可以把 props 理解为从外部传入组件内部的数据。由于 React 是单向数据流,所以 props 基本上也就是从父组件向子组件传递的数据。

1. 基础用法

<Component data="测试props"/>

现有两个组件:<ItemList/><Item/>

  1. <ItemList/>

    import Item from "./item";
    export default class ItemList extends React.Component{
      render(){
        return (
           <div>
             <Item data="我是props值"/>,
           </div>
        )
      }
    }
    
  2. <Item/>

    export default class Item extends React.Component{
      render(){
        return (
          <h1>{this.props.data}</h1>
        )
      }
    }
    

render 函数中可以看出,组件内部是使用 this.props 来获取传递到该组件的所有数据,它是一个对象,包含了所有你对这个组件的配置,现在只包含了一个 data 属性,所以通过 this.props.data 来获取即可。

这里只是对 props 的用法进行了简单的介绍,更详细、更高级的用法大家可以去官网学习哦~

2. 只读性

props 是组件的只读属性,组件内部不能直接修改 props,要想修改 props,只能在该组件的上层组件中修改。在组件状态上移的场景中,父组件正是通过子组件的 props,传递给子组件其所需要的状态。

props 经常被用作渲染组件和初始化状态,当一个组件被实例化之后,它的 props 是只读的,不可改变的。如果 props 在渲染过程中可以被改变,会导致这个组件显示的形态变得不可预测。只有通过父组件重新渲染的方式才可以把新的 props 传入组件中。

3. 默认参数

在组件使用过程中,我们最好为 props 中的参数设置一个 defaultProps,并且制定它的类型。比如这样:

Item.defaultProps = {
  item: 'Hello Props',
};

Item.propTypes = {
  item: PropTypes.string,
};

关于 propTypes 可以声明的其他类型请详见官网:使用 PropTypes 进行类型检查


state

state 的主要作用是用于组件保存、控制以及修改自己的状态,它只能在 constructor 中初始化,它是组件的私有属性,不可通过外部访问和修改,只能通过组件内部的 this.setState 来修改,修改 state 属性会导致组件的重新渲染。

1. 基础用法

在组件初始化的时候,通过 this.state 给组件设定一个初始的 state,在第一次 render 的时候就会用这个数据来渲染组件。

export default class ItemList extends React.Component{
  constructor(){
    super();
    this.state = {
      itemList:'好多数据',
    }
  }
  render(){
    return (
      {this.state.itemList}
    )
  }
}

2. 如何定义 State

我们既然要创建组件,那么就必然需要定义一个能代表一个组件UI呈现的完整状态集,也就是说:组件对应UI的任何改变,都可以从 state 的变化中反映出来;同时,state 还必须是代表一个组件UI呈现的最小状态集,即 state 中的所有状态都是用于反映组件UI的变化,没有任何多余的状态,也不需要通过其他状态计算而来的中间状态。

⚠️ 并不是组件中用到的所有变量都是组件的状态! 当存在多个组件共同依赖同一个状态时,一般的做法是状态上移,将这个状态放到这几个组件的公共父组件中。

3. 正确修改 State

1)首先,不能直接修改 State

state 不同于 props 的一点是:state 是可以被改变的。不过,不可以直接通过 this.state=xxx 的方式来修改,而需要通过 this.setState() 方法来修改 state

this.setState({title: 'React'});

⚠️ 通过 this.state=xx初始化 state,使用 this.setState修改stateconstructor唯一能够初始化的地方。

2)setState 可以接收多个参数

  • setState 接受一个对象或者函数作为第一个参数,只需要传入需要更新的部分即可,不需要传入整个对象。

    export default class ItemList extends React.Component{
      constructor(){
        super();
        this.state = {
          name: '八了个戒',
          age: 25,
        }
      }
      componentDidMount(){
        this.setState({age: 18})  
      }
    }
    

    在执行完 setState 之后的 state 应该是 {name: '八了个戒', age: 18}

  • setState 还可以接受第二个参数,它是一个函数,会在 setState 调用完成并且组件开始重新渲染时被调用,可以用来监听渲染是否完成。

    this.setState({
      name: '八戒'
    },()=>console.log('setState finished'))
    

3)State 的更新是异步的

调用 setState,组件的 state 并不会立即改变,setState 只是把要修改的状态放入一个队列中,React 会优化真正的执行时机,并且 React 会出于性能原因,可能会将多次 setState 的状态修改合并成一次状态修改。

所以不能依赖当前的 state,计算下个 state。当真正执行状态修改时,依赖的 this.state 并不能保证是最新的 state,因为 React 会把多次 state 的修改合并成一次,这时,this.state 还是等于这几次修改发生前的 state。另外需要注意的是,同样不能依赖当前的 props 计算下个 state,因为 props 的更新也是异步的。


总结

propsstate 都是普通的 JavaScript 对象。它们都是用来保存信息的,这些信息可以控制组件的渲染输出,而它们的几个重要的不同点就是:

  1. props 是传递给组件的(类似于函数的形参),而 state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)。
  2. props 是不可修改的,所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。 由于 props 是传入的,并且它们不能更改,因此我们可以将任何仅使用 props 的 React 组件视为 pureComponent(纯组件),也就是说,在相同的输入下,它将始终呈现相同的输出。
  3. state 是在组件中创建的,一般在 constructor 中初始化 state
  4. state 是多变的、可以修改,每次 setState 都异步更新的。

希望以上内容可以帮助到大家。我也是重新开始学习 React,欢迎大家一起讨论学习,最后不要忘记一键三连哦~

各位 加油!

参考内容:

  1. react中props和state有什么区别?(https://juejin.cn/post/6844903978061266957)
  2. React中state和props分别是什么?(https://segmentfault.com/a/1190000011184076)
  3. React 深入系列3:Props 和 State(https://juejin.cn/post/6844903591845724167#heading-1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【React 进阶】props 和 state 的区别详解 的相关文章

  • Angular 2 链式 Promise 并传递拒绝

    应该是一个简单的问题 但是我找不到有关如何做到这一点的文档 像这样链接一个承诺 Making a promise no problem let promise new Promise resolve reject gt let data d
  • 访问sendBeacon发送的数据

    文档表明sendBeacon通过发送其数据HTTP POST request 但在 PHP 中 POST变量似乎是一个空数组 这是我的 JavaScript 代码 navigator sendBeacon beacon log php My
  • 如何使用 selenium 和 Mocha 获取 xPath() 选择的锚标记的文本

    我已经成功选择了 a 标签 我想显示锚标记的文本 但无法这样做 我正在使用 selenium mocha javascript 和 phantomJS 这是我的脚本 详细 var assert require assert var test
  • Node js 使用中间件重定向进行过多重定向

    在我的 Node js 应用程序 我使用的是express 4 x 中 我想检查用户是否已登录 如果用户未登录 我想重定向到我的登录页面 然后我在中间件中这样做 服务器 js app use function req res next if
  • 动画进度元素值

    我有一个progress元素 该元素如下所示 div class container div div div
  • 如何在React中的Material-UI选择框中设置默认值?

    我在用选择框 https material ui com demos selects 来自材料用户界面 我想显示默认选择的 选择值 选项 但之后用户无法选择此选项
  • 如何使用 JavaScript 获取没有 HTML 元素的纯文本?

    我的 HTML 中有 1 按钮和一些文本 如下所示 function get content I don t know how to do in here
  • Javascript - 将值从下拉框传递到 Google Maps API

    我正在使用 Google 地图 API 为一家出租车公司创建报价表 目前 用户在 2 个文本框中输入出发点和接载点 API 会计算两点之间的距离以及行程费用 我正在尝试添加两个具有设定位置的下拉框 以便用户可以选择这些位置之一或使用文本框输
  • 在d3.js中将2D形状转换为3D,并根据ANGULAR中的值调整高度

    我正在使用 d3 js v6 创建以下 2D 图表表示的 3D 图表 这个圆圈中有多个正方形 每个正方形都根据值分配了一种颜色 值越大 正方形越暗 现在我想将其转换为 3D 形状 其中当值变高时 只有特定正方形的高度会增加 因此结果在某种程
  • 使用 JS 合并具有相同值的相邻 HTML 表格单元格

    我已经为此苦苦挣扎了一段时间 我有一个根据一些 JSON 数据自动生成的表 该数据可能会有所不同 我想合并第一列中具有相同值的相邻单元格 例如此表中的 鱼 和 鸟 table tr td fish td td salmon td tr tr
  • JS用正则表达式替换数字

    我有元素的标识符 如下所示 form book 1 2 3 我想要的是用其他值替换该标识符中的第二个数字 我将函数 match 与以下正则表达式一起使用 var regexp d d d 但它返回我包含的数组 1 2 3 2 因此 当我尝试
  • Select2 下拉列表动态添加、删除和刷新项目

    这让我发疯 为什么 Select2 不能在其页面上实现清晰的方法或示例如何在 Select2 上进行简单的 CRUD 操作 我有一个 select2 从 ajax 调用获取数据
  • JavaScript 代码在不使用 ActiveX 的情况下截取网站屏幕截图

    我有一个用户与之交互的 JavaScript 应用程序 我需要保存当前界面的外观 裁剪出我需要的部分 或者通过指定div只拍摄我需要的部分 然后发送回服务器 显然任何外部服务都无法做到这一点 我需要一个 JavaScript 或Flash
  • 使用 Flask/WTForms 和 React 进行 CSRF 保护

    有没有人成功地为使用 React 作为受控组件 提交到 Flask 后端 最好使用 WTForms 的表单实现了 CSRF 保护 我看过很多部分答案 其中一个是关于 Django 的 但找不到任何关于 Flask 的明确答案 我的大问题似乎
  • 单击引导分页链接时调用 jquery 函数

    我想在单击引导分页链接时调用 jquery 函数 假设我想从第1页遍历到第2页 应该调用一个jquery函数 我正在使用以下代码 但它不起作用 ul pagination on click li function alert page ch
  • 需要有关 React Js 的帮助

    我是 React Js 新手 我的代码无法正常工作 请看下面 这是我的脚本文件Main jsx 该文件由 React 编译 输出放置在 dist 文件夹下的 main js 文件中 var react require react react
  • 防止文本区域出现新行

    我正在开发聊天功能 使用 Vue 并使用文本区域作为输入 以便溢出换行 并且对于编写较长消息的用户来说更具可读性 不幸的是 当用户按下 Enter 键并提交时 光标会在提交之前移动到新行 从而使用户体验感觉不佳 关于如何使用普通 Javas
  • 使用异步调用时如何从 javascript 更新元刷新?

    我有一个系统 它使用元刷新来注销页面 该系统会在空闲用户后进行清理 不用担心 服务器也会导致会话超时 我开始通过 ajax 进行一些操作 不是真正的 xml 但这不是重点 我可以运行从异步请求返回的javascript 所以我想知道是否可以
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没
  • 在 GWT 中,在任何主机页标记上添加事件处理程序

    我想为任何标签添加 MouseOver 事件处理程序 举个例子 我想为旧版 HTML 页面中的每个锚点页面添加事件处理程序 继GWT指南 http code google com webtoolkit doc 1 6 DevGuideUse

随机推荐

  • RPC 设计与实现

    RPC 设计与实现 互联网架构演变 微观 单一架构 以实现功能为目的 扩展性差 数据访问层问题 垂直架构 业务拆分 各司其职 控制层 M V解耦 分布式服务 服务间的相互调度 RPCremote process call 流动式计算 伸缩性
  • 如何判断用户有没有关注订阅号

    收集整理的方法如下 微信用户访问微信公众号 订阅号 的网页时判断用户有没有关注公众号 订阅号 1 前提 微信公众号分为服务号和订阅号 它们的接口权限各不相同 服务号可以通过网页授权接口 用户授权后获取用户的openid 通过用户的openi
  • 如何解决过拟合与欠拟合

    如何解决过拟合与欠拟合 根据不同的坐标方式 欠拟合与过拟合图解不同 1 横轴为训练样本数量 纵轴为误差 如上图所示 我们可以直观看出欠拟合和过拟合的区别 模型欠拟合 在训练集以及测试集上同时具有较高的误差 此时模型的偏差较大 模型过拟合 在
  • GLSL 数据精度

    1 默认精度 顶点着色器中默认精度 precision highp float precision highp int precision lowp sampler2D precision lowp samplerCube 像素着色器中默认
  • 【待完善另一种情况】tensorflow 使用CPU而不使用GPU的问题解决

    文章目录 1 问题 2 Solution 3 other 4 更新 5 参考 1 问题 今天运行代码时发现一个怪现象 在使用TensorFlow时 通过os environ CUDA VISIBLE DEVICES 0 指定使用GPU 0
  • TLB的作用与机制

    TLB Translation Lookaside Buffer 转换检测缓冲区 是用来帮助CPU中的MMU进行地址转换的 在可分页系统中 每个进程都有自己虚拟地址空间和虚拟页面 当CPU执行进程代码读到虚拟地址时 不是直接将该虚拟地址送到
  • 泰勒图(Taylor diagram)绘制方法大汇总

    泰勒图 Taylor diagram 的基本介绍 R 绘制泰勒图 Taylor diagram Python 绘制泰勒图 Taylor diagram 泰勒图 Taylor diagram 的基本介绍 泰勒图 Taylor diagram
  • GEO2R数据下载速度慢、基因注释、差异分析、火山图、热图及后续处理

    GEO2R数据分析 首先感谢生信技能树大神jmzeng1314提供的github包 由于我这边访问github比较困难 因此我已经导入到我的 gitee 托管平台 https gitee com swcyo 特别声明 正版托管地址是http
  • java 工具类实现驼峰和下划线的互相转换

    下划线转驼峰 如果是下划线转驼峰 那么ch就是 public static String toCamel String str String ch if str indexOf ch 1 return str String strings
  • Git下载安装及常用命令

    背景 Git是一个开源的分布式版本控制系统 可以有效 高速的处理从很小到非常大的项目版本管理 安装 在你开始使用 Git 前 需要将它安装在你的计算机上 即便已经安装 最好将它升级到最新的版本 你可以通过软件包或者其它安装程序来安装 或者下
  • shu_1241 邮局位置问题

    http 202 121 199 212 JudgeOnline problem php cid 1078 pid 5 分析 由于题目中的距离是折线距离 所以能够分别考虑两个方向 又x方向与y方向实质是一样的 所以以下 用x方向来分析 如图
  • Linux系统vi命令快捷键汇总

    vi的基本概念 基本上vi可以分为三种状态 分别是命令模式 command mode 插入模式 Insert mode 和底行模式 last line mode 各模式的功能区分如下 命令行模式command mode 控制屏幕光标的移动
  • Linux系统网络启动失败

    nm object get property Error getting State for org freedesktop NetworkManager ActiveConnection Linux系统网络启动失败 出错原因 用图形用户界
  • Java期末作业-社区医疗信息管理系统(源码+数据库文件+设计报告·附下载链接)

    Java期末大作业 社区医疗信息管理系统介绍 比较简单 点我下载项目源码 数据库文件 设计报告文档 介绍 这个小项目没有用到任何框架也没有用到Javaweb的技术 知识使用了Java写代码 使用MySQL创建数据库 然后用JDBC进行连接
  • 什么是信道编码?信道编码比较

    消除干扰 让无线信号更干净 这本是信道编码技术的初衷 然而 最近网络上这场 Polar码投票 闹剧 无中生有地添加杂质 与所议论的技术之本质背道而驰 若Polar码也有血肉之躯 此君情何以堪 香农前辈若在世 也会笑话我们吧 2016年11月
  • 1.NoSQL数据库简介

    1 1技术发展 技术的分类 1 解决功能性的问题 Java Jsp RDBMS Tomcat HTML Linux JDBC SVN 2 解决扩展性的问题 Struts Spring SpringMVC Hibernate Mybatis
  • 服务器的作用

    服务器的作用 1 服务器就好像是一个电话总台一样 而其他的网络设备就像是公共电话 所有的数据传输都要经过服务器的处理 2 服务器作为一个网络节点 为用户提供数据处理服务 最常见的就是使用服务器为自己搭建一个网站 3 服务器运算能力强 可以长
  • Babel安装步骤(JavaScript编译器)

    首先需要安装node js按照官网 下一步 就行 1 npm init 初始化 2 安装依赖包 npm install save dev babel core babel cli 如果说提示babel不是命令 可以全局安装npm insta
  • 05-windows下SQL Developer连接Orcale

    1 使用orcale安装时候自带的工具SQL Developer 工具位置 连接 连接成功
  • 【React 进阶】props 和 state 的区别详解

    时隔一年半之久再次重新学习 React 好多都还是原来的样子 这次我要重新开启 React 的大门 希望各位小伙伴可以一起讨论学习呦 前言 今天我们开始第一个专题 React 中 关于 props 和 state 当然我们不是对 props