React 状态和生命周期

 

以下内容原文来自:https://facebook.github.io/react/docs/state-and-lifecycle.html

 

Start:

State and Lifecycle

 

01,想一下之前的 ticking clock 例子;到目前为止,我们只学习了跟新UI界面的一种方法-->

-----> 我们调用React.render() 方法去改变渲染出来的界面;

------>

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(//渲染
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

在这节文章,我们将会学习如何创建/封装一个可复用的Clock组件,它可以设定自己的时间,而且可以每秒钟自己更新时间

我们暂时将clock封装成这个样子:

--->

function Clock(props) {//组件
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

但是这样写忽略了一个关键需求:设置时间和每秒钟更新时间,应该是Clock组件本身来实现的细节

理想中,我们希望写的像下面的代码,同时可以实现Clock组件自己更新时间;

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

为了能够实现这个,我们需要在Clock组件中添加 state 状态;

state 和 props 类似,但是它是私有的,完全被组件所控制;

我们之前提到过,定义为Class 的组件有一些附加的特性 --> local state 只能用于 class;

 

Converting a Function to a Class /将function定义的组件转换为class定义

1.用es6 class name extends React.Component

2.添加 redder 方法

3.将原先function 中的函数体 放到 render 方法中

4. 用this.props 替换props 

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

Adding Local State to a Class/添加状态

1. 用this.state.date替换this.props.data

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) {//构造函数  注意这里传了 props **##Class components should always call the base constructor with 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 prop 从Clock组件中删除

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

到此为止 代码如下

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>
    );
  }
}

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

接下来,让clock组件自己跟新

Adding Lifecycle Methods to a Class/添加生命周期方法

在拥有很多组件的应用中,当组件销毁时,释放组件所占的资源很重要;

每当clock 组件第一次渲染时,我们就设置一个计时器 ,----> mounting 

每当clock 组件移除时,我们就清空计时器 -----> unmounting

--->声明生命周期函数方法

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {//已经渲染到dom
         this.timerID = setInterval(//
          () => this.tick(),
          1000
          );
  }

  componentWillUnmount() {
        clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }
    
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}         


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

-->关系<--

1.<Clock/>组件传递到 ReactDom.render() 后,React 调取Constructor,组件需要显示当前时间->

this.state将会被更新

2.React 调用 组件的render()方法,将组件跟新到Dom;

3.组件更新到Dom后,React 调用componentDidMount()钩子-->组件通知浏览器设置timer

4.每次调用tick()方法,组件会调setState()方法,React知道state改变以后重新调用render()方法

5. 假如组件从Dom中移除,React 调用componentWillUnmoint()  停止timer

Using State Correctly/正确使用State

1.不要直接修改state

// Wrong
this.state.comment = 'Hello';

// Instead, use setState(): Correct
this.setState({comment: 'Hello'});

2.state 的更新可能是异步的,不能依赖它们的值,正确的做法是

setState()接收一个函数,函数接收previous state 作为参数

// Wrong  this code may fail to update the counter:
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

 

posted @ 2017-06-29 11:31  Terre  阅读(511)  评论(0编辑  收藏  举报

风光无限好