好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

React中props与state

以下内容均为个人理解。

1.state:

在react中,state可以看成管理页面状态的集合(实则一个对象而已),库里面的成员均为页面渲染变量,整个页面为一个状态机,当state发生变化时,页面会重新渲染,页面随state变化而变化。

2.state如何正确使用:

const eventsArr =  [
     'handleText1Change' ,
     'handleText2Change' ,
     'handleText3Change' 
];

const EmptyString  = "" ;

class Dome extends React.Component {
    constructor(props) {
        super(props);
          this .state =  {
            text1: EmptyString,
            text2: EmptyString,
            text3: EmptyString,
            flag:   true  
        };
          this  .setBindFunc();
    };

    setBindFunc() {
        eventsArr.forEach(ev  =>  {
              this [ev] =  this [ev].bind( this  );
        })
    };

    handleText1Change(e) {
          this  .setState({
            text1: e.target.value
        });
    };

    handleText2Change(e) {
          this .state.text2 =  e.target.value;
          this  .setState({});
    };

    handleText3Change(e) {
          this  .setState({
            text3: e.tarege.value
        }, ()  =>  {
              this .state.flag =  false  ;
        })
    };

    render() {
          return  <div>
            <input type='text' value={ this .state.text1} onChange={ this .handleText1Change} />
            <input type='text' value={ this .state.text2} onChange={ this .handleText2Change} />
            <input type='text' value={ this .state.text3} onChange={ this .handleText3Change} />
        </div>
     };
}; 

state控制页面渲染,但是只给state赋值是不会导致页面刷新的,只有调用this.setState({})方法后才会执行render方法,最后导致页面重新渲染。

第一种写法:

this.setState({text1: e.target.value})为最常规的写法,执行完此方法之后会执行render方法,刷新state中的text1值。但是这里有个问题就是this.setState({})本身作为异步函数,赋值与渲染上会有先后问题,

在执行this.setState({text1: e.target.value})这个方法是,实际上this.state.text1的值没有改变。当走到render里面的时候this.state.text1的值才会发生改变,render内原则不可以写过多的赋值逻辑,如何解决呢产生方法二。

第二种写法:

this.state.text2 = e.target.value; 这种赋值可以直接改变this.state.text2的值,然后调用this.setState({})重新渲染页面,这种方式不会存在异步问题(只要调用this.setState({}),render函数是必然会走的,除非使用

shouldComponentUpdate来加以限制)。

第三种写法:

this.setState({},()=>{})这种赋值与第一种一样,主要侧重在回调函数上,回调函数是在执行完render后执行,回调函数内可以写逻辑,我们拿个简单的赋值举例。这种方式可以控制组件渲染的先后顺序。

1.props:

props是组件之间传递数据的媒介。那么在使用props时应该注意哪些。

   1   const
    2      eventsArr =  [
    3          'handleText1Change' ,
    4          'handleText2Change' ,
    5          'handleText3Change' ,
    6          'handleText4Change'
   7       ];
    8  
   9  const EmptyString = "" ;
   10  
  11   class Dome extends React.Component {
   12       constructor(props) {
   13           super(props);
   14           this .state =  {
   15               text1: EmptyString,
   16               text2: EmptyString,
   17               text3: EmptyString,
   18               text4: EmptyString,
   19               obj: {
   20                   value: EmptyString
   21               },
   22              flag:  true 
  23           };
   24           this  .setBindFunc();
   25       };
   26  
  27       setBindFunc() {
   28          eventsArr.forEach(ev =>  {
   29               this [ev] =  this [ev].bind( this  );
   30           })
   31       };
   32  
  33       handleText1Change(e) {
   34           this  .setState({
   35               text1: e.target.value
   36           });
   37       };
   38  
  39       handleText2Change(e) {
   40           this .state.text2 =  e.target.value;
   41           this  .setState({});
   42       };
   43  
  44       handleText3Change(e) {
   45           this  .setState({
   46               text3: e.tarege.value
   47          }, () =>  {
   48               this .state.flag =  false  ;
   49           })
   50       };
   51  
  52       handleText4Change(oldValue, newValue) {
   53           this .state.text4 =  newValue;
   54       };
   55  
  56       render() {
   57           return  <div>
  58              <input type='text' value={ this .state.text1} onChange={ this .handleText1Change} />
  59              <input type='text' value={ this .state.text2} onChange={ this .handleText2Change} />
  60              <input type='text' value={ this .state.text3} onChange={ this .handleText3Change} />
  61              < DomeChildren
   62                  text4={ this  .state.text4}
   63                  obj={ this  .state.obj}
   64                  handleText4Change={ this  .handleText4Change}
   65              />
  66          </div>
  67       };
   68   };
   69  
  70   const
   71      Constants =  {
   72          Click: 'Click'
  73       };
   74  
  75   class DomeChildren extends React.Component() {
   76       constructor(props) {
   77           super(props);
   78           this .state =  {
   79              text:  this  .props.text4,
   80              obj:  this  .props.obj
   81           };
   82       };
   83  
  84       handleText4Change(e) {
   85           let
   86              oldValue =  this  .state.text,
   87              newValue =  e.target.value;
   88           this .state.text =  newValue;
   89           this  .setState({});
   90           this  .props.handleText4Change(oldValue, newValue);
   91       };
   92  
  93       handleClick() {
   94           //  仅做例子用 
  95           this .props.text4 = "Dqhan" ;
   96           this .props.obj.value = 10086 ;
   97       }
   98  
  99       render() {
  100           return  <div>
 101              <input type='text' value={ this .state.text} handleText4Change={ this .handleText4Change.bind( this )} />
 102              <div onClick={ this .handleClick.bind( this )}>{Constants.Click}</div>
 103          </div>;
 104       };
  105  };

首先props是用于组件之间传递信息的,比如父组件Dome传递给子组件DomeChildren了text4,obj跟一个方法handleText4Change,这里我们达到了props作用的目的,当子组件内执行handleText4Change,改变了DemoChildren里面的text值同时渲染该组件,这里没有影响到Demo,同时DomeChildren将oldValue与newValue通过传递的handleText4Change方法暴露给了Demo,达到了父给子传递,子给父传递的,子组件渲染没有影响到父级的目的,我理解这是最正确的传递方式以及组件之间的关系。当执行handleClick方法时,可以看到代码执行this.props.text4="Dqhan"时react会报错,这说明props是不可以改变的,但是this.props.obj.value = 10086没有报错,很明显,因为obj是对象,这里我理解为,只要物理地址没有变,react就会认为是props没有改变,不然很多地方用到了数组就没招了。总结:props中简单类型不能改变,引用类型内部的属性可以改变。

补充一下,创建组件时用的ES6语法class关键字,熟悉服务器语言的都知道,一个类是通常情况下实例化然后才能使用的(除工具类等),而react中<Demo />便是实例化这个组件(react自己封装的)得出一个对象。

 

查看更多关于React中props与state的详细内容...

  阅读:32次