React中的props和state的理解

news/2024/11/13 3:44:06/

props:

        props是一个从外部传递进组件的参数。由于React具有单向数据流的特性,所以它的主要作用是从父组件向子组件中传递数据,它是不可改变的,如果想要改变它,只能通过外部组件传入新的props来从新渲染子组件,否则子组件的props和展示形式不会改变,props除了可以传递字符串、数字外。还可以传递对象、数组甚至是回调函数等等。

 state:

        state主要作用是用于组件保存、控制以及修改自己的状态。它只能在constructor中初始化,state是可以被改变的,state放改动的一些属性,比如点击选中、再点击取消,类似这种属性就放入带state中。注意:没有state的叫做无状态组件,多用props少用state,多写无状态组件,注意:修改state的值时,必须通过调用setState方法,当我们调用this.setState方法时,React会更新组件的数据状态,并且重新调用render方法

 props 和 state 本质

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

props

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

 1、基本用法

<Component data="测试props"/>

现有两个组件:<组件A/> 和 <组件B/> 

①  <组件A/>

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

② <组件B/>

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

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

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 的更新也是异步的。



http://www.ppmy.cn/news/1059789.html

相关文章

铜矿人员定位安全方案

针对铜矿中的人员定位安全需求&#xff0c;可以采用以下方案&#xff1a; 1.实时人员定位系统&#xff1a;建立一个实时人员定位系统&#xff0c;通过在矿工的工作服或安全帽上安装UWB或RFID定位设备&#xff0c;以及相应的接收器和基站&#xff0c;实时跟踪和定位矿工的位置。…

Golang Gorm 一对多关系 关系表创建

一对多关系 我们先从一对多开始多表关系的学习因为一对多的关系生活中到处都是&#xff0c;例如&#xff1a; 老板与员工女神和添狗老师和学生班级与学生用户与文章 在创建的时候先将没有依赖的创建。表名称ID就是外键。外键要和关联的外键的数据类型要保持一致。 package ma…

Go 语言的实战案例 SOCKS5 代理 | 青训营

Powered by:NEFU AB-IN 文章目录 Go 语言的实战案例 SOCKS5 代理 | 青训营 引入TCP echo serverauth 认证请求阶段relay阶段 Go 语言的实战案例 SOCKS5 代理 | 青训营 GO语言工程实践课后作业&#xff1a;实现思路、代码以及路径记录 引入 代理是指在计算机网络中&#xff…

【随笔】如何使用阿里云的OSS保存基础的服务器环境

使用阿里云OSS创建一个存储仓库&#xff1a;bucket 在Linux上下载并安装阿里云的ossutil工具 // 命令行&#xff0c;是linux环境 3. 安装ossutil。sudo -v ; curl https://gosspublic.alicdn.com/ossutil/install.sh | sudo bash 说明:安装过程中&#xff0c;需要使用解压工具…

iptables的使用规则

环境中为了安全要限制swagger的访问&#xff0c;最简单的方式是通过iptables防火墙设置规则限制。 在测试服务器中设置访问swagger-ui.html显示如下&#xff0c;区分大小写&#xff1a; iptables设置限制访问9783端口的swagger字段的请求&#xff1a; iptables -A INPUT -p t…

【图像分割】实现snake模型的活动轮廓模型以进行图像分割研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

opencv 案例实战02-停车场车牌识别SVM模型训练及验证

1. 整个识别的流程图&#xff1a; 2. 车牌定位中分割流程图&#xff1a; 三、车牌识别中字符分割流程图&#xff1a; 1.准备数据集 下载车牌相关字符样本用于训练和测试&#xff0c;本文使用14个汉字样本和34个数字跟字母样本&#xff0c;每个字符样本数为40&#xff0c;样本尺…

【Python】P0 本系列博文简介与大纲

Python 前言本系列博文适合谁本系列博文不适合谁本系列博文大纲 前言 本系列博文基于《Python Cookbook》一书&#xff0c;Python 3 版本&#xff1b;本系列博文的目标不是为了构建一个 Python 知识大全&#xff0c;而是为了那些需要快速将 Python 学以致用的相关人员&#xf…