在React中,数据是自顶向下流动的(称为单项数据流),从父组件传递到子组件。因此组件是简单且易于把握的,它们只需从父节点获取props渲染即可。如果顶层组件的某个prop改变了,React会递归向下遍历整个组件树,从新渲染所有使用这个属性的组件。
然而在React中出了props之外还有自己的状态,这些状态只能在组件内修改,那这个状态就是state
props:就是properties的缩写,你可以使用它把任意类型的数据传递给组件(通俗一点就是,可以当成方法传递的参数)
state:当前组件内部数据
props
可以在挂载组件的时候设置它的props
<Component title="标题" /> var data = { name : "刘宇",title : "标题" }; <Component {...data} />
在组件内部调用的话就是使用 this.props
//Comment.js import React,{ Component } from 'react';、 import './Comment.css'; class Comment extends Component { render() { return ( <div className="Comment"> {/**接受参数**/} {this.props.name} {/**接受子节点**/} {this.props.children} </div> ); } } export default Comment; //App.js class App extends Component { render() { return ( <div className="App"> {/**调用组件**/} <Comment name="刘宇" /**传递参数**/>组件插入内容{/**子节点**/}</Comment> </div> ); } } export default App; //index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import './index.css'; ReactDOM.render( <App />,document.getElementById('root') );
propTypes
propTypes用于规范props的类型与必须的状态。如果组件定义了propTypes,那么在开发环境下,就会对组件的props值的类型作检查,如果传入的props不能与之匹配,React将实时在控制台里报warning(警告);
static propTypes = { // 你可以定义一个js原始类型的prop,默认请情况下,这是都是可选的 optionalArray: React.PropTypes.array,optionalBool: React.PropTypes.bool,optionalFunc: React.PropTypes.func,optionalNumber: React.PropTypes.number,optionalObject: React.PropTypes.object,optionalString: React.PropTypes.string,optionalSymbol: React.PropTypes.symbol,// 任何可以渲染的东西:数字,字符串,元素或数组(或片段)。 optionalNode: React.PropTypes.node,// React元素 optionalElement: React.PropTypes.element,// 你也可以声明prop是某个类的实例。 内部使用的是JS的instanceof运算符。 optionalMessage: React.PropTypes.instanceOf(Message),// 你可以通过将它作为枚举来确保你的prop被限制到特定的值。 optionalEnum: React.PropTypes.oneOf(['News','Photos']),// 可以是许多类型之一的对象 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string,React.PropTypes.number,React.PropTypes.instanceOf(Message) ]),// 某种类型的数组 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),// 具有某种类型的属性值的对象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),// 采取特定样式的对象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string,fontSize: React.PropTypes.number }),// 你可以用`isrequired`来连接到上面的任何一个类型,以确保如果没有提供props的话会显示一个警告。 requiredFunc: React.PropTypes.func.isrequired,// 任何数据类型 requiredAny: React.PropTypes.any.isrequired,// 您还可以指定自定义类型检查器。 如果检查失败,它应该返回一个Error对象。 不要`console.warn`或throw,因为这不会在`oneOfType`内工作。 customProp: function(props,propName,componentName) { if (!/matchme/.test(props[propName])) { return new Error( 'Invalid prop `' + propName + '` supplied to' + ' `' + componentName + '`. Validation Failed.' ); } },// 您还可以为`arrayOf`和`objectOf`提供自定义类型检查器。 如果检查失败,它应该返回一个Error对象。 // 检查器将为数组或对象中的每个键调用验证函数。 // 检查器有两个参数,第一个参数是数组或对象本身,第二个是当前项的键。 customArrayProp: React.PropTypes.arrayOf(function(propValue,key,componentName,location,propFullName) { if (!/matchme/.test(propValue[key])) { return new Error( 'Invalid prop `' + propFullName + '` supplied to' + ' `' + componentName + '`. Validation Failed.' ); } }) }; //以上是ES6的写法,如果使用的是createClass MyComponent.propTypes = { //同上 }
要求只能是单个子元素
class MyComponent extends React.Component { render() { // 只能包含一个子元素,否则会给出警告 const children = this.props.children; return ( <div>{children}</div> ); } } MyComponent.propTypes = { children: React.PropTypes.element.isrequired }
getDefaultProps和defaultProps
可以为组件添加getDefaultProps来设置属性的默认值。
//es6写法 class Comment extends Component { //设置默认props值 static defaultProps = { name:"默认值" } render() { return ( <div className="Comment"> {/**接受参数**/} {this.props.name} {/**接受子节点**/} {this.props.children} </div> ); } } var Comment = React.createClass( { //设置默认props值 getDefaultProps : { name:"默认值" },render : function(){ return ( <div className="Comment"> {/**接受参数**/} {this.props.name} {/**接受子节点**/} {this.props.children} </div> ); } })
state
state是组件内部的属性。组件本身是一个状态机,他可以在constructor中通过this.state直接定义他的值,然后根据这些值来渲染不同的UI,当state的值发生改变时,可以通过this.setState方法让组件再次调用render方法,来渲染新的UI.
var Comment = React.createClass( { //设置state值 getInitialState : { num:0 },addNum : function(){ var num = this.state.num++; this.setState({ num:num }) },render : function(){ return ( <div className="Comment"> <button onClick>{this.state.num}</button> </div> ); } }) //es6写法 class Comment extends Component { constructor(props) { super(props); this.state = { num : 0 }; this.addNum = this.addNum.bind(this) } addNum() { var num = this.state.num++; this.setState({ num:num }) } render() { return ( <div className="Comment"> <button onClick>{this.state.num}</button> </div> ); } }