React属性与状态

属性和状态作为组件之间数据流动的途径。

单向数据流

单向数据流:更新 DOM 的数据总是从顶层流下来,用户事件不直接操作 DOM,而是操作顶层数据。这些数据从顶层流下来同时更新了 DOM。这就如同「云腾致雨,露结成霜」一样是大自然的规律。

在React中,数据的流向是单向的——从父节点传递到子节点,因而组件是简单且易于把握的,它们只需要从父节点获取props渲染即可。如果顶层组件的某个prop改变了,React会递归地向下遍历整颗组件树,重新渲染所有使用这个属性的组件。

属性(props)

属性(props):类似 HTML 中的属性,绘制时可在标签中添加属性,然后在组件中通过 this.props.属性名 获取。props属性是父组件控制子组件的单向数据流传输的关键。

使用props注意事项

  1. props类似HTML的属性
  2. props只读,不能使用this.props修改
  3. props用于整个组件树种传递数据和配置
  4. 访问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条依据进行判断:

  1. 这个变量是否是通过Props从父组件中获取?如果是,那么它不是一个状态。
  2. 这个变量是否在组件的整个生命周期中都保持不变?如果是,那么它不是一个状态。
  3. 这个变量是否可以通过其他状态(State)或者属性(Props)计算得到?如果是,那么它不是一个状态。
  4. 这个变量是否在组件的render方法中使用?如果不是,那么它不是一个状态。这种情况下,这个变量更适合定义为组件的一个普通属性,例如组件中用到的定时器,就应该直接定义为this.timer,而不是this.state.timer
  5. 这个变量修改后,是否要更新组件?是,那么它是一个状态。

设置默认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属性与状态相关推荐

  1. 【React系列】状态(State)和生命周期

    在上一篇中写过,组件可以分为函数式组件和类组件,并且更新组件的方法也给出了通过传入ReactDOM.render()方法进行更新.但是这种方式并不能很好地进行封装成独立功能的组件,一些操作会由外部进行 ...

  2. react怎么存上一页_如何实现 React 中的状态自动保存?

    什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目, ...

  3. react中数据状态管理的四种方案

    我们为什么需要状态管理? (1) 一个是为了解决相邻组件的通信问题. 虽然可以通过「状态提升」解决,但有两个问题: 每次子组件更新,都会触发负责下发状态的父组件的整体更新(使用 Context 也有这 ...

  4. React属性之Refs

    React属性之Refs 1 介绍 2 使用方法 2.1 createRef(版本>=React16.3) 2.2 回调Refs 2.3 String类型的Refs(已过时,不推荐使用) 2.4 ...

  5. react 使用 mobx_如何使用React和MobX状态树构建基于状态的路由器

    react 使用 mobx by Miles Till 由Miles Till 如何使用React和MobX状态树构建基于状态的路由器 (How to build a state-based rout ...

  6. [react] 描述下在react中无状态组件和有状态组件的区别是什么?

    [react] 描述下在react中无状态组件和有状态组件的区别是什么? 1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板 ...

  7. [react] 在react中无状态组件有什么运用场景

    [react] 在react中无状态组件有什么运用场景 适用于逻辑简单的纯展示的场景,如资料卡片等 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主 ...

  8. React基础——组件状态state、属性props

    import React from 'react'; // 此句不能少 import ReactDom from 'react-dom';class Taggle extends React.Comp ...

  9. React学习:状态(State) 和 属性(Props)

    React :元素构成组件,组件又构成应用. React核心思想是组件化,其中 组件 通过属性(props) 和 状态(state)传递数据. State 与 Props 区别 props 是组件对外 ...

最新文章

  1. 启动hadoop的节点
  2. arduino蓝牙通讯代码_「Arduino」OLED屏使用教程,显示内容听谁的?我不管,听我的...
  3. 【转载】C ++ 基础 指针 引用
  4. 【ArcGIS风暴】在ArcGIS中实现将一个圆16等分
  5. oracle 8i漏洞渗透,一次通过Oracle8i入侵系统之旅(组图)
  6. 2021年全国研究生数学建模指导
  7. everything的安装后初始设置
  8. ManyCam Enterprise(摄像头特效软件)v6.7.0.34版
  9. ToStringBuilder学习
  10. 你的脑容量(字符串问题,小技巧)
  11. java新闻发布系统源代码_Java新闻发布系统源代码
  12. STM32操作增量式编码器(一)----使用外部中断实现测速
  13. mysql 5.6 免安装版_mysql 5.6.15的免安装版 安装
  14. 用于拆解和组合PDF中各个对象的shell脚本
  15. Linux服务器cpu性能模式,linux cpu开启性能模式
  16. 竖子不足与谋(转自天下三国)
  17. 无需破解,官网安装Visual Studio 2013社区版
  18. Shell Tools and Scripting
  19. 力扣146题 LRU 缓存机制
  20. 深圳财经生活频道--杨百万

热门文章

  1. 在家远程控制(远程桌面)到公司的电脑
  2. 关于TCP长连接的一些简单代码
  3. CF514B Han Solo and Lazer Gun
  4. 排序算法(冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序)
  5. centos 7安装matlab的两种方法(桌面安装和命令行安装)
  6. 操作系统第三次实验——线程基础总结
  7. 数据可视化分析工具如何在国内弯道超车,迅速崛起?
  8. 汽车配件管理系统分析报告
  9. 数学建模:9 多元线性回归分析
  10. android安全问题(八)伪造短信(利用原生android4.0漏洞)