React属性与状态
React属性与状态
属性和状态作为组件之间数据流动的途径。
单向数据流
单向数据流:更新 DOM 的数据总是从顶层流下来,用户事件不直接操作 DOM,而是操作顶层数据。这些数据从顶层流下来同时更新了 DOM。这就如同「云腾致雨,露结成霜」一样是大自然的规律。
在React中,数据的流向是单向的——从父节点传递到子节点,因而组件是简单且易于把握的,它们只需要从父节点获取props渲染即可。如果顶层组件的某个prop改变了,React会递归地向下遍历整颗组件树,重新渲染所有使用这个属性的组件。
属性(props)
属性(props):类似 HTML 中的属性,绘制时可在标签中添加属性,然后在组件中通过 this.props.属性名 获取。props属性是父组件控制子组件的单向数据流传输的关键。
使用props注意事项
- props类似HTML的属性
- props只读,不能使用this.props修改
- props用于整个组件树种传递数据和配置
- 访问props,需要通过this.props.属性名 获取传递的属性值
属性使用键值对
// 这个键值对可以是字符串: <Hello name="winty"/>// 可以是大括号:大括号包裹的求值表达式 <Hello name={123}/> <Hello name={"king"}/>// 可以是一个数组:这样属性拿到的也是一个数组 <Hello name={[1,2,3]}/> 传入数组// 可传入变量:变量可以在外部定义,在组件内去引用 变量的值可为任何类型 <Hello name={winty}/> 变量
在组件中使用属性
class HelloMessage extends React.Component{render() {return <h1>Hello {this.props.name}</h1>;} } ReactDOM.render(<HelloMessage name="John" />, document.getElementById('example') );
其中props 可以认为是一个配置接口,在使用 HelloMessage 组件的时候,传入的任何html属性都会保存在组件 this.props 中。
属性使用展开定义
var attr={ one:"11", two:"22" }
这样定义的话,理论上使用应该是one={attr.one}这样调用,但是这样写起来比较繁琐,而且如果数据被修改,就需要对应修改相应的赋值,并且无法动态地设置属性,所以react中添加了一种展开语法:
<Hello {...attr}/> //也就是三个点加上对象名称
这样使用展开语法,react就会自动把对象中的变量和值当作是属性的赋值,所以Hello实际上就拿到了one、two两个属性,如果没有三个点的话,Hello拿到的实际上就是attr对象,使用的时候还需要自己从中取出变量和值
为组件定义默认属性
可以通过如下两种方式来设置属性的默认值。
//方式1: class Test extends React.Component{static defaultProps = {name:'everyone'}constructor(props){super(props);}render(){return (<div>{this.props.name}</div>); } }//方式2: class Test extends React.Component{constructor(props){super(props);}render(){return (<div>{this.props.name}</div>); } } Test.defaultProps = {name:'everyone' }
使用 PropTypes 进行类型检查
注意: 从 React v15.5 开始 ,React.PropTypes 助手函数已被弃用,我们建议使用 prop-types 库 来定义contextTypes。
PropTypes包
名称 | 链接 |
---|---|
PropTypes | https://www.npmjs.com/package/prop-types |
安装
npm install prop-types
引入
import PropTypes from 'prop-types'; // ES6 var PropTypes = require('prop-types'); // ES5 with npm
使用
PropsTypes是React中用来定义props的类型,不符合定义好的类型会报错。建议可复用组件要使用prop验证!接着上面的列子设置PropsTypes如下:
# 写法一: class Test extends React.Component{static defaultProps = {name:'everyone'}constructor(props){super(props);}render(){return (<div>{this.props.name}</div>); } } Test.propTypes = {name:PropTypes.string }<Test name="'houningzhou'" /> # 写法二: class Test extends React.Component{static defaultProps = {name:'everyone'}static propTypes = {name:PropTypes.string}constructor(props){super(props);}render(){return (<div>{this.props.name}</div>); } }<Test name="'houningzhou'" /> React.PropTypes 提供很多验证器 (validator) 来验证传入数据的有效性。官方定义的验证器如下,不是使用ES6语法。MyComponent.propTypes = {// 可以声明 prop 为指定的 JS 基本类型。默认情况下,这些 prop 都是可传可不传的。 optionalArray: PropTypes.array,optionalBool: PropTypes.bool,optionalFunc: PropTypes.func,optionalNumber: PropTypes.number,optionalObject: PropTypes.object,optionalString: PropTypes.string,optionalSymbol: PropTypes.symbol,// 所有可以被渲染的对象:数字,字符串,DOM 元素或包含这些类型的数组(or fragment) 。 optionalNode: PropTypes.node,// React 元素 optionalElement: PropTypes.element,// 你同样可以断言一个 prop 是一个类的实例。 用 JS 的 instanceof 操作符声明 prop 为类的实例。 optionalMessage: PropTypes.instanceOf(Message),// 你可以用 enum 的方式 确保你的 prop 被限定为指定值。optionalEnum: PropTypes.oneOf(['News', 'Photos']),// 指定的多个对象类型中的一个 optionalUnion: PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.instanceOf(Message)]),// 指定类型组成的数组 optionalArrayOf: PropTypes.arrayOf(React.PropTypes.number),// 指定类型的属性构成的对象 optionalObjectOf: PropTypes.objectOf(React.PropTypes.number),// 特定形状参数的对象 optionalObjectWithShape: PropTypes.shape({color: PropTypes.string,fontSize: PropTypes.number}),// 你可以在任意东西后面加上 `isRequired` 来确保 如果 prop 没有提供 就会显示一个警告。 requiredFunc: PropTypes.func.isRequired,// 不可空的任意类型 requiredAny: PropTypes.any.isRequired,// 你可以自定义一个验证器。如果验证失败需要返回一个 Error 对象。// 不要直接使用 `console.warn` 或抛异常,// 因为这在 `oneOfType` 里不起作用。customProp: function(props, propName, componentName) {if (!/matchme/.test(props[propName])) {return new Error('Validation failed!');}} };
状态(State)
State介绍
状态 state:使用this.state来引用,state本身就是状态的意思,状态指的是事物所处的状况,状况就是环境。
通常使用state存储简单的视图状态,比如说下拉框是否显示、单选 是否选中,或者需要自身去维护的变化数据等。
注意:
状态是事物自己处理的,不和属性一样,属性是天生的,事物一般来说没有办法修改。
状态是事物本身的是事物的私有属性,也就是由自己决定,父组件和子组件都不能改变他。给定了状态就一定知道结果是什么。
组件中用到的某个变量是不是应该作为组件State,可以通过下面的5条依据进行判断:
- 这个变量是否是通过Props从父组件中获取?如果是,那么它不是一个状态。
- 这个变量是否在组件的整个生命周期中都保持不变?如果是,那么它不是一个状态。
- 这个变量是否可以通过其他状态(State)或者属性(Props)计算得到?如果是,那么它不是一个状态。
- 这个变量是否在组件的render方法中使用?如果不是,那么它不是一个状态。这种情况下,这个变量更适合定义为组件的一个普通属性,例如组件中用到的定时器,就应该直接定义为
this.timer
,而不是this.state.timer
。 - 这个变量修改后,是否要更新组件?是,那么它是一个状态。
设置默认state
class Test extends React.Component{constructor(props){super(props);//默认状态this.state = {isShow:true}}render(){return <div style={display:this.state.isShow?'block':'none'}>This is component!</div> } }
修改state
直接修改state,组件并不会重新重发render。例如:
// 错误
this.state.title = 'React';
state可以通过setState来修改,只要setState被调用,render就会被调用。如果render函数的返回值有变化,虚拟DOM就会更新,真实的DOM也会被更新,最终用户可以在浏览器中看到变化。
this.setState({})
setState会触发diff算法:判断state和页面结果的区别,是否需要更新
案例
class Timer extends React.Component{constructor(props){super(props);this.state = {sec: 1}}add(){this.setState({sec:this.state.sec+1});},componentDidMount(){setInterval(this.add,1000);},render(){return ( <div style={this.style}>过去了:{this.state.sec}秒钟</div>); } } ReactDOM.render(<Timer/>,document.getElementById('demo'));
State 的更新是异步的
当我们调用setState时,组件的state病不会立即修改,setState只是把要修改的状态放入到一个队列中,React会优化真正的执行时机,并且出于性能原因,可能会将多次setState的状态修改合并在一次状态修改。所以不要依赖当前的state去计算下一个state。
state 和 props 之间有什么区别?
props 和 state 都是在改变时会触发一次重新渲染的 JavaScript 对象。虽然两者都具有影响渲染输出的信息,但它们在一个重要方面是不同的: props 传递到组件(类似于函数参数),而 state 是在组件内管理的(类似于函数中声明的变量)。
state
不要在state中保存计算出的值,而应该保存简单的数据。
状态:下拉菜单是否显示、输入框的值、变化的数据、选项卡的选中状态
props
props作为数据源存在,使用props在整个组件树中传递数据。
转载于:https://www.cnblogs.com/wkyuan/p/11328148.html
React属性与状态相关推荐
- 【React系列】状态(State)和生命周期
在上一篇中写过,组件可以分为函数式组件和类组件,并且更新组件的方法也给出了通过传入ReactDOM.render()方法进行更新.但是这种方式并不能很好地进行封装成独立功能的组件,一些操作会由外部进行 ...
- react怎么存上一页_如何实现 React 中的状态自动保存?
什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目, ...
- react中数据状态管理的四种方案
我们为什么需要状态管理? (1) 一个是为了解决相邻组件的通信问题. 虽然可以通过「状态提升」解决,但有两个问题: 每次子组件更新,都会触发负责下发状态的父组件的整体更新(使用 Context 也有这 ...
- React属性之Refs
React属性之Refs 1 介绍 2 使用方法 2.1 createRef(版本>=React16.3) 2.2 回调Refs 2.3 String类型的Refs(已过时,不推荐使用) 2.4 ...
- react 使用 mobx_如何使用React和MobX状态树构建基于状态的路由器
react 使用 mobx by Miles Till 由Miles Till 如何使用React和MobX状态树构建基于状态的路由器 (How to build a state-based rout ...
- [react] 描述下在react中无状态组件和有状态组件的区别是什么?
[react] 描述下在react中无状态组件和有状态组件的区别是什么? 1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板 ...
- [react] 在react中无状态组件有什么运用场景
[react] 在react中无状态组件有什么运用场景 适用于逻辑简单的纯展示的场景,如资料卡片等 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主 ...
- React基础——组件状态state、属性props
import React from 'react'; // 此句不能少 import ReactDom from 'react-dom';class Taggle extends React.Comp ...
- React学习:状态(State) 和 属性(Props)
React :元素构成组件,组件又构成应用. React核心思想是组件化,其中 组件 通过属性(props) 和 状态(state)传递数据. State 与 Props 区别 props 是组件对外 ...
最新文章
- 启动hadoop的节点
- arduino蓝牙通讯代码_「Arduino」OLED屏使用教程,显示内容听谁的?我不管,听我的...
- 【转载】C ++ 基础 指针 引用
- 【ArcGIS风暴】在ArcGIS中实现将一个圆16等分
- oracle 8i漏洞渗透,一次通过Oracle8i入侵系统之旅(组图)
- 2021年全国研究生数学建模指导
- everything的安装后初始设置
- ManyCam Enterprise(摄像头特效软件)v6.7.0.34版
- ToStringBuilder学习
- 你的脑容量(字符串问题,小技巧)
- java新闻发布系统源代码_Java新闻发布系统源代码
- STM32操作增量式编码器(一)----使用外部中断实现测速
- mysql 5.6 免安装版_mysql 5.6.15的免安装版 安装
- 用于拆解和组合PDF中各个对象的shell脚本
- Linux服务器cpu性能模式,linux cpu开启性能模式
- 竖子不足与谋(转自天下三国)
- 无需破解,官网安装Visual Studio 2013社区版
- Shell Tools and Scripting
- 力扣146题 LRU 缓存机制
- 深圳财经生活频道--杨百万