React-数据流详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liujie19901217/article/details/73015401

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

React组件内部还具有自己的状态,这些状态只能在组件内修改。React组件本身很简单,你可以把它们称为一个函数,它接受props和state作为参数,返回一个虚拟的Dom表现。

Props

props是properties的缩写,可以用它将任意类型的数据传递给组件。

  • 可以在挂载组件的时候设置它的props:
var surveys = [
{
title:'Superheroes'
}
];
<ListSurveys surveys={surveys}/>

或者使用调用实例的setProps方法(很少需要这样做)来设置props:

var surveys =[ 
{
title:superheroes
}
];
var listSurveys = React.render(
<ListSurveys/>,
document.querySelector('body');
);
listSurveys.setProps({
surveys:surveys
})

你只能在子组件上或者组件树外(如上例)调用setProps,一定不可以调用this.setProps或者直接修改this.props,如果有需要,可以使用state。可以使用this.props访问props,但是绝对不能通过这种方式修改它,一个组件绝对不可以自己修改自己的props。

  • 在JSX中可以把props设置成字符串:
<a href='/surveys/add'>
Add survey
</a>

也可以使用{}语法来设置,注入javaScript传递任意类型的变量:

<a href={'/surveys/'+survey.id}>
{survey.title}
</a>

还可以使用JSX的展开语法吧props设置成一个对象:

var ListSurveys = Reacty.createClass({
render:function(){
var props={
one:‘foo’,
two:‘bar'
};
return<SurveyTable {...props}/>;
}
});
  • props还可以用来添加事件处理器:
var SaveButton = React.creatClass({
render:fucntion(){
return(
<a className ='button save' onclick={this.handleClick}>Save</a>
);
},
handleClick:function(){
//事件处理
}
});

这里传递了一个onClick属性,值为handleClick函数,当用户点击链接时,handlelick方法被调用。

PropTypes

通过组建定义一个配置对象,React提供了一种验证props的方式:

var SurveyTableRow =React.creatClass({
propTypes:{
survey:React.Proptypes.shape({
id : React.Proptypes.number.isRequired
}).isRequired,
onClick:react.PropTypes.func
},
});

组件初始化时,如果传递的属性和propTypes不匹配,则会打印一个console.warn日志。如果是可选的配置,则额可以去掉.isRequired
在应用中使用propTypes并不是强制的。

getDefauleProps

可以为组件添加getDefaultProps函数来设置属性的默认值,不过这应该只针对那些非必需属性:

varSurveyTable=React.createClass({
getDefaultProps:function(){
return{
surveys:[]
};
}
//...
});

必须知道的是getDefaultProps并不是在组件实例化时被调用的,而是在React.createClass调用时被调用了,返回值会被缓存起来,也就是说不能再getDefaultProps中使用任何特定的实例数据;

State

每一个State组件都可以拥有自己的state,state与props的区别在于前者只存在于组件的内部。state可以用来确定一个元素的试图状态。我们看一个自定义的<Dropdown/>组件:

var CountryDropdown=React.createClass({
getInitialState:function(){
        return:{
showOptions:false
};
},

render:function(){
var option;
if(this.state.showOptions){
options =(
<ul clasName ='options'>
<li>United Stated of America</li>
<li>newZealand</li>
</ul>
);
}

return(
<divclassName ='dropdown' onClick={this.handClick}>
</div>
);
},

handleClick:function(){
this.setState({
showOptions:true
});
}
});

在上面例子中,state用来记录是否在下拉框中显示可选项。
state可以通过setState来修改,可以使用getInitalState方法提供一组默认值。只要setState被调用,render就会被调用。如果render函数返回值有变化,虚拟DOM就会更新,真实的DOM就会被更新。
注意:一定不可以直接修改this.state,永远要通过this.setState方法修改。

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

不要再state中保存计算出的值,而应该保存最简单的数据,即组件正常工作时的必要的数据。比如用来表示下拉框是否显示的布尔值,又比如输入框的值,等等。
不要尝试将props复制到state中,要尽可能的把props当作数据源。

总结

  • 使用props在整个组建树种传递数据和配置。
  • 避免在组件内部修改this.props或者调用this.setProps,把props当作是只读的。
  • 使用props来做时间处理器,与子组件通信。
  • 使用state存储简单的试图状态,比如说下拉框是否可见这样的状态。
  • 使用this.setState来设置状态,不要使用this.state直接修改状态
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页