React:数据流
在React中,数据的流向是 单向 的---从父节点传递到子节点。当顶层组件的某个prop改变了, React会递归地向下遍历整棵组件树,重新渲染所有使用这个属性的组件。
var data=[{title:'props'}];
<MyView data={data}/>
var data=[{title:'props'}];
var myView=React.render({
<MyView/>,
document.body
});
myView.setProps({data:data});
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')
);
var MyView=React.createClass({
propTypes:{
title:React.PropTypes.isRequired,
onClick:React.PropTypes.func
},
...
});
//基本类型
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');
}
}
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直接修改状态。
更多建议: