浅谈React之状态(State)


Posted in Javascript onSeptember 19, 2018

在React当中,当你更新组件的state,然后新的state就会重新渲染到页面中。在这个时候不需要你操作任何DOM。你也可以认为组件在React当中是一个状态机(State Machines)。当用户进行操作时会实现不同的状态,然后再渲染到你的页面中,让你的页面与数据始终保持一致。

如何定义State

定义一个合适的State,是正确创建组件的第一步。State必须能代表一个组件UI呈现的完整状态集,即组件的任何UI改变,都可以从State的变化中反映出来;同时,State还必须是代表一个组件UI呈现的最小状态集,即State中的所有状态都是用于反映组件UI的变化,没有任何多余的状态,也不需要通过其他状态计算而来的中间状态。

组件中用到的一个变量是不是应该作为组件State,可以通过下面的4条依据进行判断:

1.这个变量是否是通过Props从父组件中获取?如果是,那么它不是一个状态。

2.这个变量是否在组件的整个生命周期中都保持不变?如果是,那么它不是一个状态。

3.这个变量是否可以通过其他状态(State)或者属性(Props)计算得到?如果是,那么它不是一个状态。

4.这个变量是否在组件的render方法中使用?如果不是,那么它不是一个状态。这种情况下,这个变量更适合定义为组件的一个普通属性,例如组件中用到的定时器,就应该直接定义为this.timer,而不是this.state.timer。

如果对状态不好理解的朋友,你可以认为状态即是数据!

State 与 Props 区别

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

主要区别:

  1. State是可变的,是一组用于反映组件UI变化的状态集合;
  2. 而Props对于使用它的组件来说,是只读的,要想修改Props,只能通过该组件的父组件修改。
    在组件状态上移的场景中,父组件正是通过子组件的Props, 传递给子组件其所需要的状态

现在我们先来通过ES6类React.Component完成一个通过点击按钮对DIV进行显示与隐藏的操作,效果如下:

浅谈React之状态(State)

咱们先将页面进行初始化:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    #myDiv{
      width:200px;
      height:400px;
      background:red;
      color:yellow;
      border:1px solid green;
    }
  </style>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/react.development.js"></script>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/react-dom.development.js"></script>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/babel.min_.js"></script>
</head>
<body>
  <div id="wrap"></div>
</body>
<script type="text/babel">
  class MyComponent extends React.Component{
    constructor(props){
      super(props);
      // 为当前状态添加isShow属性
      this.state={
        // 值为true显示,false为隐藏。默认值为true。
        isShow:true
      }
    }
    render(){
      //返回组件的初始内容
      return <div>
        <input type="button" value="显示与隐藏"/>
        <div id="myDiv">我在这里呀!</div>
      </div>
    }
  }
  ReactDOM.render(
    <MyComponent/>,
    document.querySelector("#wrap")
  )
</script>
</html>

到目前为止,页面已经初始化完毕了。在上面的代码中为state添加了一个默认值为true的属性isShow。isShow用来控制div的显示与隐藏!当isShow为true时显示,为false时隐藏

接下来要完成的二件事。

第一件事是要为按钮增加一个点击事件,事件与changeState方法进行绑定。当点击按钮时改变isShow的状态,也就是要为 isShow进行取反操作。

注意:

1、onClick中的c要大写。
2、onClick后跟的方法不要用引号包裹,而是用{}
3、在ES6的class中React是不会自动绑定this的,所以需要自己通过bind绑定。
4、changeState方法中,不能直接修改isShow的值,而是需要借助setState方法来进行设置。

第二件事是要为id为myDiv的DIV增加一个style属性,该属性要根据isShow的状态来对DIV进行显示与隐藏

注意:

1、style的值不要用双引号,而是用{},否则会报错

最终版代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    #myDiv{
      width:200px;
      height:400px;
      background:red;
      color:yellow;
      border:1px solid green;
    }
  </style>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/react.development.js"></script>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/react-dom.development.js"></script>
  <script src="https://zhangpeiyue.com/wp-content/uploads/2018/08/babel.min_.js"></script>
</head>
<body>
<div id="wrap"></div>
</body>
<script type="text/babel">
  class MyComponent extends React.Component{
    constructor(props){
      super(props);
      // 为当前状态添加isShow属性
      this.state={
        // 值为true显示,false为隐藏。默认值为true。
        isShow:true
      }
    }
    changeState(){
      //此处不能直接修改isShow的值。而是需要借助setState方法!
      this.setState({
        //取反操作
        isShow:!this.state.isShow
      });
    }
    render(){
      //返回组件的初始内容
      return <div>
        {/*在ES6的class中React是不会自动绑定this的,所以需要自己绑定*/}
        <input type="button" value="显示与隐藏" onClick={this.changeState.bind(this)} />
        <div id="myDiv" style={{display:this.state.isShow?'block':'none'}}>
          我在这里呀!
        </div>
      </div>
    }
  }
  ReactDOM.render(
    <MyComponent/>,
    document.querySelector("#wrap")
  )
</script>
</html>

由上面的示例可以发现,当你改变isShow的状态时,div也会发生相对应的变化!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 新手学习常见问题解决方法
Apr 18 Javascript
详解JS 比较两个Json对象的值是否相等的实例
Nov 20 Javascript
JavaScript 判断用户输入的邮箱及手机格式是否正确
Dec 08 Javascript
Jquery获取元素的父容器对象示例代码
Feb 10 Javascript
基于Jquery+Ajax+Json实现分页显示附效果图
Jul 30 Javascript
AngularJS辅助库browserTrigger用法示例
Nov 03 Javascript
基于canvas的二维码邀请函生成插件
Feb 14 Javascript
在Vue项目中使用snapshot测试的具体使用
Apr 16 Javascript
微信小程序 组件的外部样式externalClasses使用详解
Sep 06 Javascript
node.js中Buffer缓冲器的原理与使用方法分析
Nov 23 Javascript
Vue-cli打包后如何本地查看的操作
Sep 02 Javascript
解决vue加scoped后就无法修改vant的UI组件的样式问题
Sep 07 Javascript
jQuery使用each遍历循环的方法
Sep 19 #jQuery
vue新vue-cli3环境配置和模拟json数据的实例
Sep 19 #Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
Sep 19 #Javascript
vue-cli 3.0 自定义vue.config.js文件,多页构建的方法
Sep 19 #Javascript
vue.extend与vue.component的区别和联系
Sep 19 #Javascript
webpack+vue+express(hot)热启动调试简单配置方法
Sep 19 #Javascript
自己动手封装一个React Native多级联动
Sep 19 #Javascript
You might like
我的论坛源代码(八)
2006/10/09 PHP
Smarty Foreach 使用说明
2010/03/23 PHP
比较时间段一与时间段二是否有交集的php函数
2011/05/31 PHP
PHP使用imagick读取PDF生成png缩略图的两种方法
2014/03/20 PHP
PHP使用DOM和simplexml读取xml文档的方法示例
2017/02/08 PHP
jQuery chili图片远处放大插件
2009/11/30 Javascript
jcrop基本参数一览
2013/07/16 Javascript
jQuery实现等比例缩放大图片让大图片自适应页面布局
2013/10/16 Javascript
js使用post 方式打开新窗口
2015/02/26 Javascript
JavaScript中的原始值和复杂值
2016/01/07 Javascript
微信小程序 教程之模块化
2016/10/17 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
vue中实现methods一个方法调用另外一个方法
2018/02/08 Javascript
VUE基于NUXT的SSR 服务端渲染
2018/11/30 Javascript
详解ES6 Promise的生命周期和创建
2019/08/18 Javascript
Vue分页插件的前后端配置与使用
2019/10/09 Javascript
vue data引入本地图片的两种方式小结
2019/11/13 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
[02:44]2014DOTA2 国际邀请赛中国区预选赛 大神红毯秀
2014/05/25 DOTA
python小技巧之批量抓取美女图片
2014/06/06 Python
python获取当前日期和时间的方法
2015/04/30 Python
使用Python编写一个最基础的代码解释器的要点解析
2016/07/12 Python
python with提前退出遇到的坑与解决方案
2018/01/05 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
利用Python实现Shp格式向GeoJSON的转换方法
2019/07/09 Python
Python项目 基于Scapy实现SYN泛洪攻击的方法
2019/07/23 Python
Python使用matplotlib 模块scatter方法画散点图示例
2019/09/27 Python
Idea安装python显示无SDK问题解决方案
2020/08/12 Python
基于python的opencv图像处理实现对斑马线的检测示例
2020/11/29 Python
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
养殖行业的创业计划书
2014/01/05 职场文书
高二英语教学反思
2014/01/19 职场文书
毕业生就业推荐表自我评价
2015/03/02 职场文书
综合素质评价个性与发展自我评价
2015/03/06 职场文书
2019年最新版见习人员管理制度!
2019/07/08 职场文书
Python如何解决secure_filename对中文不支持问题
2021/07/16 Python