从零一起学react(4)---组件的props和state

来源:互联网 发布:pink原宿风拍照软件 编辑:程序博客网 时间:2024/06/05 20:11

前言

react组件具有props成员和state成员,这两个成员都是object类型,而props和state的主要区别是:props不可变,而state可以根据和用户的互交来改变。

props

1.获取props

先看一段代码。

class Hello extends React.Component {  render() {    return (<h1>Hello {this.props.mes}</h1>);  }}ReactDOM.render(  <Hello mes="world" />,  document.getElementById('test'));

这段代码中创建组件在上一篇文章中讲过,不同的地方是我们在ReactDOM.render()中给了组件Hello一个属性 mes=”Hello world” ,然后在创建组件的代码中使用{this.props.mes}来获取该属性的值,this.props.mes就是这个组件的props成员的mes属性。这样浏览器中显示出Hello world,说明获取到了mes属性的值。

2.默认props

我们可以用 Hello.defaultProps 给props属性设置一个默认值,这样我们在使用组件但没有给出属性值时,会显示默认值,例如。

class Hello extends React.Component {  render() {    return <h1>Hello {this.props.name}</h1>;  }}Hello.defaultProps = { name: 'buppt'};ReactDOM.render(  <Hello />,  document.getElementById('test'));

这样在没有给name属性时,会默认显示’Hello buppt’,如果给出name属性如 < Hello name=’world’/> 将会显示 ‘Hello world’。

上面代码是在class外部定义的属性,在组件内部定义的写法如下。

class Hello extends React.Component {  static defaultProps = {    name: 'buppt'  }  render() {    return <h1>Hello {this.props.name}</h1>;  }}

组件内定义在create-react-app和react native中都是可以的,但是我们用babel设置es6的转码方式,运行会报错,因为定义静态属性不属于es6,而在es7的草案中。ES6的class中只有静态方法,没有静态属性。这里我们知道可以这样定义就好啦。

3.props属性验证

我们可以用 propTypes 给props属性设置一个类型限定,例如。

class Hello extends React.Component {  //组件内设置如下  //static propTypes = { name: React.PropTypes.string.isRequired,}  render() {    return <h1>Hello {this.props.name}</h1>;  }}//组件外设置如下//Hello.propTypes = { name: React.PropTypes.string.isRequired};//var myName=123;var myName="buppt";ReactDOM.render(  <Hello name={myName} />,  document.getElementById('test'));

本来我还在想为什么按照上面的写法会出错,原来官网都有说明:

注意: React.PropTypes 自 React v15.5 起已弃用。请使用 prop-types 库代替。

所以更详细的props属性验证说明可以看《从零一起学react(6)》。

4.this.props.children

这里先说明一下,组件使用时不一定要写成<组件名 />这样,还可以写成<组件名><组件名/>。
每一个组件的props都有一个children属性,这个属性将返回所有在<组件名><组件名/>之间的内容。例如:

class Hello extends React.Component {  render() {    return <h1>Hello {this.props.children}</h1>;  }}ReactDOM.render(  <Hello>    <span>I am buppt.</span>    <br/>    <span>Nice to meet you!</span>  </Hello>,  document.getElementById('test'));

将显示出’Hello I am buppt. Nice to meet you!’。

state

1.获取state

和props不同,state不是从<组件名/>中传进来的,而是组件自己的状态。例如:

class Hello extends React.Component {  constructor(props){    super(props);    this.state = { mood: 'happy' };  }  render() {    return <h1>I am {this.state.mood}</h1>;  }}ReactDOM.render(  <Hello/>,  document.getElementById('test'));

浏览器将会显示’I am happy’,至于为什么要先调用super(props),用百度上说:

调用super的原因:在ES6中,在子类的constructor中必须先调用super才能引用this。
super(props)的目的:在constructor中可以使用this.props。
根本原因是constructor会覆盖父类的constructor,导致你父类构造函数没执行,所以手动执行下。

2.使用setState更新state

使用this.setState()可以更新(改变)this.state中的属性值。先贴一段代码。

class Hello extends React.Component {  constructor(props){    super(props);    this.state = { color: 'green' };    this.changeColor = this.changeColor.bind(this);  }   changeColor() {    this.setState({ color: 'yellow' });  }   render() {    return (      <div style={{background: this.state.color}}>        <h1>          Change my color        </h1>        <button onClick={this.changeColor}>Change color</button>      </div>    );  }}ReactDOM.render(<Hello />, document.getElementById('test'));

如果尝试运行一下这段代码,你就知道这段代码的作用就是,点击按钮,可以将div的背景颜色从绿色改为黄色,这说明点击按钮,改变了this.state.color的值。

其中用到了.bind(this),想具体了解的可以看一下官方文档,以后我可能会具体写一下,这个bind的作用简言之就是使changeColor()无论怎样调用都有相同的this。

这篇文章就到这里把~大家可以再敲一下下面这个代码具体感受一下。

class Hello extends React.Component {  constructor(props){    super(props);    this.state = { color: 'green' };    this.changeColor = this.changeColor.bind(this);  }  changeColor() {    const newColor = this.state.color == 'green' ? 'yellow' : 'green';    this.setState({ color: newColor });  }  render() {    return (      <div style={{background: this.state.color}}>        <h1>          Change my color        </h1>        <button onClick={this.changeColor}>Change color</button>      </div>    );  }}ReactDOM.render(<Hello />, document.getElementById('test'));