React学习笔记-8-属性和状态详解

Posted Gabriel_wei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React学习笔记-8-属性和状态详解相关的知识,希望对你有一定的参考价值。

  1. 属性的含义和用法
    props=properties 英文中属性的意思。属性不可以修改,也就是属性不可以由组件进行修改,组件的属性是由父组件传递过来的,相当于组件在出生的时候带的。

    用法
    第一种:直接在调用组件的时候传入一个键值对,
      这个键值对可以是字符串:
    <HelloWorld name="李明"></HelloWorld>

      可以是大括号:大括号本质上是一个js的求值表达式,里面可以写很多内容,最简单的就是写数据,直接拿到的数字

    <HelloWorld name={123}></HelloWorld>

    可以是大括号,里面是字符串:他的值就是里面的字符串,当然在实例的使用中,我们直接入第一个一样使用。

    <HelloWorld name={"Tim"}></HelloWorld>

    可以是一个数组:这样属性拿到的也是一个数组,在编写多选框和表单的时候用的多看,组件可以根据传入的属性来构建子组件

    <HelloWorld name={[1,2,3]}></HelloWorld>

    可以直接传入一个变量:这个变量可以在外部定义,然后在组件里面去引用他。变量可以是一个数组,对象,字符串,数值都可以,

    <HelloWorld name={variable}></HelloWorld>

    可以是函数求值表达式:就是直接定义一个函数并调用他,一个的形式就是两个括号放在一起,这样我们就可以定义一个匿名函数并调用他,大括号的值就是匿名函数的返回值.


    第二种:可以理解为展开,我们使用这三个点,就可以直接把里面的值拿出来,可以拿到两个属性,如果把三个点去掉,HelloWorld拿到的就是一个props对象,还得自己展开。

    var  props={
           one:"123",
           two:321,
       }
    
    <HelloWorld {...props} />

    这个props有两个属性,一个one,一个two,如果我们使用第一种键值对的方式,就得写两个,这样写起来比较繁琐,而且我们如果修改props,就得修改下面的属性引用。代码的可维护性不高,而且动态性不高。

    var  props={
           one:"123",
           two:321,
       }
    
    <HelloWorld  one={props.one}  two={props.two} />

     

    第三种:最不常用的,setProps可以设置组件的属性,他接受的参数是一个对象,他会用这个对象来更新属性,但是在实际使用中,很好用这个因为我们是不能够在组件内部去修改属性的,这样会违背react的设计原则。在组件外部直接用上面两种。
    instance.setProps({name:"Tom"})



  2. 实例
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello world</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f09",
    
            };
            var HelloWorld=React.createClass({
            render: function(){
                  return <p>Hello,{this.props.name ? this.props.name : "world"}</p>
              },
            });
            var HelloUniverse=React.createClass({
                  getInitialState:function(){
                       return {name:\'\'};
                  },
                  handleChange:function(event){
                       this.setState({name:event.target.value});
                  },
                  render:function(){
                    return <div>
                             <HelloWorld name={this.state.name}></HelloWorld>
                            <br/>
                            <input type="text" onChange={this.handleChange} />
                          </div>              
                  },
            });
            React.render(<div style={style}><HelloUniverse></HelloUniverse></div>,document.body);
    
        </script>
    </body>
    </html>

    注意图中的红色标记区域,如果把div和return分开放在两行就会报错,如下

    报错:
    Uncaught Error: Invariant Violation: HelloUniverse.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.


    修改代码使用第二种赋值方式:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello world</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f09",
    
            };
            var HelloWorld=React.createClass({
            render: function(){
                  return <p>Hello,{this.props.name1+\' \'+this.props.name2}</p>
              },
            });
            var HelloUniverse=React.createClass({
                  getInitialState:function(){
                       return {
                          name1:\'tom\',
                          name2:\'John\',
                          };
                  },
                  handleChange:function(event){
                       this.setState({name:event.target.value});
                  },
                  render:function(){
                       return <div>
                             <HelloWorld {...this.state}></HelloWorld>
                            <br/>
                            <input type="text" onChange={this.handleChange} />
                          </div>              
                  },
            });
            React.render(<div style={style}><HelloUniverse></HelloUniverse></div>,document.body);
    
        </script>
    </body>
    </html>


    第三种:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello world</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f09",
    
            };
            var HelloWorld=React.createClass({
            render: function(){
                  return <p>Hello,{this.props.name ? this.props.name : "world"}</p>
              },
            });
            var instance=React.render(<HelloWorld></HelloWorld>,document.body);
            //这里返回的是react的返回值,这里设置的是HelloWorld的属性,并且render函数进行了更新
            instance.setProps({name:\'tom\'})
    
        </script>
    </body>
    </html>

     

  3. 状态的含义和用法
    状态 state:使用this.state来引用,state本身就是状态的意思,状态指的是事物所处的状况,状况就是环境。注意:状态是事物自己处理的,不和属性一样,属性是天生的,事物一般来说没有办法修改。状态是事物本身的是事物的私有属性,也就是由自己决定,父组件和子组件都不能改变他。给定了状态就一定知道结果是什么。

    用法:
    getInitialState:初始化每个实例特有的状态
    setState:更新组件状态,原则上是经常使用的,但是setProps原则上面不推荐你使用,

    setState会触发的行为,他会调用diff算法。

    实例:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>hello world</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            var style={
               color:"red",
               border:"1px solid #f09",
    
            };
            var HelloWorld=React.createClass({
            render: function(){
                  return <p>Hello,{this.props.name}</p>
              },
            });
            var HelloUniverse = React.createClass({
               getInitialState: function(){
                   return {
                       name: \'Tom\',
                   };
               },
               handleChange:function(event){
                   this.setState({name:event.target.value});
               },
               render: function(){
                   return <div>
                   <HelloWorld name={this.state.name}></HelloWorld>
                   <br />
                   <input type="text" onChange={this.handleChange} />
                   </div>
               },
            });
            React.render(<div style={style}><HelloUniverse></HelloUniverse></div>,document.body)
    
        </script>
    </body>
    </html>



  4. 属性和状态对比
    属性和状态的相似点:
    4.1.1都是纯js对象
    4.1.2都会触发render函数更新
    4.1.3都具有确定性
       状态相同,结果一定相同,这就是确定性。给定了相同的属性或者相同的状态,结果都是一样的。

                                               属性          状态
    能否在父组件获取初始值                 可以             不可以
    能否有父组件进行修改                     可以            不可以
    能否在组件内部设置默认值                可以           可以
    能否在组件内部修改                         不可以           可以
    能否设置子组件的初始值                  可以               不可以
    能否修改子组件的初始值                   可以              不可以




  5. 如何区分属性和状态
    组件在运行时需要修改的数据就是状态。
    属性的核心要点就是不能修改!


  6. 属性和状态实战
    编写一个简单的文章评论框
    第一步:分析构成项目的组件。         第二步:分析组件的关系及数据传递        第三步:编写代码

    6.1添加两个组件,并用React.render渲染到页面上,Content内容组件,Comment评论框组件。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>属性和状态实战</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
        <script type="text/jsx">
            //子组件
            var Content=React.createClass({
                render:function(){
                    return <p>content</p>;
                },
            });
            //父组件
            var Comment = React.createClass({
                render:function(){
                    //我们现在东西是写死的,下一个例子的写法是动态的生成。
                    return <Content></Content>;
                },
            });
            React.render(<Comment></Comment>,document.body);
        </script>
    </body>
    </html>

    6.2在Comment里面添加一个下拉列表

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>属性和状态实战</title>
    </head>
    <body>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script>
        <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script>
       

    以上是关于React学习笔记-8-属性和状态详解的主要内容,如果未能解决你的问题,请参考以下文章

    React学习笔记2

    React 学习笔记总结

    React 学习笔记总结

    DOM探索之基础详解——学习笔记

    python学习笔记8--面向对象--属性和方法详解

    React学习笔记-4-什么是生命周期