jsx 封装clock,将函数组件转换成 class 组件

我们可以从封装时钟的外观开始:

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()} />,//初始化date
    document.getElementById('root')
  );
}

setInterval(tick, 1000);//注意行代码在外面自己运行,一会将会进行封装

运行:https://codepen.io/gaearon/pen/dpdoYR?editors=0010

然而,它忽略了一个关键的技术细节:Clock 组件需要设置一个计时器,并且需要每秒更新 UI。(组件本身自己调用,而不是外部运行)

理想情况下,我们希望只编写一次代码,便可以让 Clock 组件自我更新

代码如下:

ReactDOM.render(
  <Clock />,//这里不用传初始化
  document.getElementById('root')
);

我们需要在 Clock 组件中添加 “state” 来实现这个功能。

State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。

将函数组件转换成 class 组件

通过以下五步将 Clock 的函数组件转成 class 组件:

  1. 创建一个同名的 ES6 class,并且继承于 React.Component
  2. 添加一个空的 render() 方法。
  3. 将函数体移动到 render() 方法之中。
  4. 在 render() 方法中使用 this.props 替换 props
  5. 删除剩余的空函数声明。
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

现在 Clock 组件被定义为 class,而不是函数。

每次组件更新时 render 方法都会被调用,但只要在相同的 DOM 节点中渲染 <Clock /> ,就仅有一个 Clock 组件的 class 实例被创建使用。这就使得我们可以使用如 state 或生命周期方法等很多其他特性。

向 class 组件中添加局部的 state(封装)

我们通过以下三步将 date 从 props 移动到 state 中:

  1. 把 render() 方法中的 this.props.date 替换成 this.state.date :
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

        2.添加一个 class 构造函数,然后在该函数中为 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>
    );
  }
}

Class 组件应该始终使用 props 参数来调用父类的构造函数。

        3. 移除 <Clock /> 元素中的 date 属性:

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

运行:https://codepen.io/gaearon/pen/KgQpJd?editors=0010

 

官网:https://react.docschina.org/docs/state-and-lifecycle.html

posted @ 2020-12-16 13:28  听声是雨  阅读(183)  评论(0编辑  收藏  举报