React:数据流

2018-06-19 10:55 更新

在React中,数据的流向是 单向 的---从父节点传递到子节点。当顶层组件的某个prop改变了, React会递归地向下遍历整棵组件树,重新渲染所有使用这个属性的组件。

React组件内部还具有自己的状态,这些状态只能在组件内修改。
我们可以将React组件看成一个函数,它接受props和state作为参数,返回一个虚拟的DOM表现。

一、Props
props properties 的缩写,可以使用它把任意类型的数据传递给组件。

我们如何设置组件的props?
1.可以在挂载组件时设置props:

var data=[{title:'props'}];

<MyView data={data}/>

2.调用组件实例的setProps方法(不常用):

var data=[{title:'props'}];

var myView=React.render({

  <MyView/>,

  document.body

});

myView.setProps({data:data});


注意:我们可以通过this.props访问props,但是千万别调用 this.setProps或者直接修改this.props。

小技巧:

var CheckLink = React.createClass({   

  render: function() {   

    // 这样会把 CheckList 所有的 props 复制到 <a>   

    return <a {...this.props}>{'√ '}{this.props.children}</a>;   

  }  

});   

React.render(   

  <CheckLink href="/checked.html">   

    Click here!   

  </CheckLink>,   

  document.getElementById('example')  

);


PropTypes
propTypes方法是React提供的一种验证props的方式(一般在开发环境下才使用):

var MyView=React.createClass({

  propTypes:{

    title:React.PropTypes.isRequired,

    onClick:React.PropTypes.func

  },

  ...

});

在组件初始化时,如果传递的属性和propTypes不匹配,则会打印一个console.warn日志。

propTypes内置验证器合集

//基本类型

React.PropTypes.array

React.PropTypes.bool

React.PropTypes.func

React.PropTypes.number

React.PropTypes.object

React.PropTypes.string


//所有可以被渲染的对象:数字,字符串,DOM元素或包含这些类型的数组。

React.PropTypes.node


//React元素

React.PropTypes.element


//用js的instanceof操作符声明prop为类的实例

React.PropTypes.instanceOf(Object)


//用enum来限制prop只接受指定的值

React.PropTypes.oneOf(['a','b'])


//指定的多个对象类型中的一个

React.PropTypes.oneOfType([

  React.PropTypes.number,

  React.PropTypes.string

])


//指定类型组成的数组

React.PropTypes.arrayOf(React.PropTypes.number)


//指定类型的属性构成的对象

React.PropTypes.objectOf(React.PropTypes.number)


//特定格式参数的对象

React.PropTypes.shape({

  color:React.PropTypes.string,

  fontSize:React.PropTypes.number

})


//必需值

React.PropTypes.number.isRequired


//必需不为空的任意类型

React.PropTypes.any.isRequired




自定义验证器

customPropType:function(props,propName,componentName){

  if(!/[0-9]/.test(props[propName]){

    return new Error('inValid');

  }

}

注意:不要使用 console.warn 或 throw ,因为它在 oneOfType 的情况下无效。

getDefaultProps

在组件中,我们可以添加getDefaultProps函数来设置属性的默认值。

var MyView=React.createClass({

  getDefaultProps:function(){

    return {

      title:[]

    }

  }

});

注意:getDefaultProps并不是在组件实例化时被调用,而是在React.createClass调用时就被调用了,返回值会被缓存起来。


二、State(状态)

每一个React组件都可以拥有自己的state。


state与props的区别?

state只存在于组件的内部。


getInitialState

我们可以用getInitialState方法来提供一组默认值。

var MyView=React.createClass({

  getInitialState:function(){

    return {

      isShow:false

    }

  },

  render:function(){

    var view;

    if(!this.state.isShow){

      view=(

        <div className='item'>item</div>

      );

    };

    return (

      <div className='view'>{view}<button onClick={this.handleClick}>显示</button></div>

    );

  },

  handleClick:function(){

    var isShow=!this.state.isShow;

    this.setState({

      isShow:isShow

    });

  }

});


state还可以通过 setState replaceState 修改。只要setState或replaceState被调用,render就会被调用。一旦render的返回值有变化,页面会实时变化。


replaceState会用一个全新的state对象完整的替换掉原有的state,而setState只会将传入的对象合并到已有的state对象中。


注意:永远不要直接修改this.state,要通过 this.setState 方法来修改。


放在state和props的各是哪些部分?

不要在state中保存计算出的值,而应该只保存最简单的数据,即那些组件正常工作时的必要数据。

不要尝试把props复制到state中,要尽可能把props当做数据源。


总结

  • 使用props在整个组件树中传递数据和配置
  • 避免在组件内部修改this.props或调用this.setProps,把props看作只读。
  • 使用props来做事件处理器,与子组件通信
  • 使用state来存储简单的视图状态
  • 使用 this.setState 来设置状态,不要使用this.state直接修改状态。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号