react基础03-状态state

React状态

       React的状态一般要先在构造函数中进行初始化声明。

  constructor(props) {
    super(props);
    //初始化状态,将所有的状态都放到下面的state对象里面
    this.state = {
        date: new Date()
        ....
    };
  }

 React的状态的修改一定要使用setState,如下:

  constructor(props) {
    super(props);
    //初始化状态,将所有的状态都放到下面的state对象里面
    this.state = {
        date: new Date(),
        num:0,
        ....
    };
  }
  componentDidMount(){
    // 修改状态中的num的值
        this.setState({
          num:20
        })
  }

   案例,下面是一个显示当前时间的组件,时间使用props传递的(可以看组件传值讲解),页面显示的是固定的值不能实时变化,

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>  // It is 下午2:08:20.
      </div>
    );
  }
}
ReactDOM.render(
  <Clock date={new Date()}/>,
  document.getElementById("app")
) 

现在我们要实现时间实时变化更新的功能 :

      将本地状态添加到类中,我们将date参数分三步从props转移到state

1.更换this.props.date用this.state.date的render()方法:
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
---------------------------------------------------------------------------
2.添加一个分配初始化的类构造函数创建本地状态this.state,
class Clock extends React.Component {
  constructor(props) {
    super(props);
    //初始化状态
    this.state = {date: new Date()};
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
---------------------------------------------------------------------------
3.date从<Clock />元素中删除prop :
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

将生命周期方法添加到类中:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() { // 组件装载完成,更新数据
    this.timerID = setInterval( // 每隔1秒,调用this._tick(),更新状态
      () => this._tick(),
      1000
    );
  }
  componentWillUnmount() { // 组件销毁时,删除定时器
    clearInterval(this.timerID);
  }
  render() { // 渲染视图组件
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
  _tick() { // 自定义方法,更新状态的值
    this.setState({
      date: new Date()
    });
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

 让我们快速回顾一下上面的组件执行过程,发生了什么以及调用这些方法的顺序:

    1.当<Clock />被传递到ReactDOM.render(),Clock组件构造函数constructor被执行。初始化本地状态this.state

    2.然后React调用Clock组件的render()方法。更新DOM以匹配Clock渲染输出。

    3.当Clock输出插入DOM时,React会调用componentDidMount()生命周期方法。在其中设置了一个计时器,每秒调用一次组件的方法tick()。

    4.浏览器每次调用该tick()方法。Clock组件通过setState()方法更新state。由于setState()调用,React知道状态已经改变,会再次调用render()重新渲染。此时,this.state.date在render()方法中是改变后的值。

    5.如果Clock组件从DOM中删除,React会调用componentWillUnmount()生命周期方法,来停止计时器。

state的正确使用:

//不要直接修改状态:
this.state.comment = 'Hello';   // 错误

//使用setState():
this.setState({comment: 'Hello'});  // 正确

 状态更新可能是异步的:

this.setState({
  counter: this.state.counter + this.props.increment,
});

    上例中,this.props和this.state可以异步的,所以不应该依赖它们的值来计算下一个状态。上面的代码可能无法更新计数器,此时要使用第二种形式setState()接受函数而不是对象,如下:

this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

箭头函数:
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

单组件中props和state区别 

    1.固定不变的数据放在props,变化的数据放在state中。props主要用途用于复合组件中父子组件之间的传值

    2.props里面的数据是只读的,只能读取,不能更改设置。state里面的数据既可以读取也可以更改

class Dog extends React.Component{
  constructor(props){
    super(props)
    //初始化状态
    // 姓名,性别,年龄,朋友
    this.state = {
    	age : 1,
    	friends:["花花","小红"]
    }
  }
  //设置props属性的默认值
  static defaultProps = {
    name:"旺财",
    gender:"公"
  }
  //设置props属性的类型(需要外部引入prop-types.js)
  static propTypes = {
    name:PropTypes.string.isRequired, // 必传项
    gender:PropTypes.string,
  }
  changeAge(){
    this.setState({
      age:this.state.age+1
    })
  }
  render(){
    const {name,gender} = this.props
    const {age,friends} = this.state
    return (
      <div>
        <p>狗名:{name},性别:{gender}</p>
        <p>年龄:{age}</p>
        <p>朋友</p>
        <ul>
          {
            friends.map((friend,index)=>(
              <li key={index}>{friend}</li>
            ))
          }
        </ul>
        <button onClick={()=>this.changeAge()}>点击增长年龄</button>
      </div>
    )
  }
}
ReactDOM.render(<Dog name="" gender="母" />,document.getElementById('app'))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值