zoukankan      html  css  js  c++  java
  • ④ state & 生命周期

    1 如何封装真正可复用的 Clock 组件

    1.1 封装时钟的外观

    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 组件需要设置一个计时器,并且需要每秒更新 UI

    实现 Clock 组件自我更新

    ReactDOM.render(
        <Clock />,
        document.getElementById('root')
      );
    
    • 需要在 Clock 组件中添加 state 来实现组件的自我更新

    • Stateprops 类似,但是 state 是私有的,并且完全受控于当前组件

    1.2 将函数组件转换成 class 组件

    class Clock extends React.Component {
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is { this.props.date.toLocaleTimeString() }.</h2>
          </div>
        );
      }
    }
    
    • 每次组件更新时 render 方法都会被调用,但只要在相同的 DOM 节点中渲染,就仅有一个 Clock 组件的 class 实例被创建使用

    1.3 向 class 组件中添加局部的 state

    • 通过以下三步将 dateprops 移动到 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 {
      // 将props传递到父类的构造函数中
      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. 移除 <Clock /> 元素中的 date 属性
    ReactDOM.render(
      <Clock />,
      document.getElementById('root')
    )
    

    1.4 将生命周期方法添加到 class 中

    1. 在组件被挂载到 DOM 后运行
    componentDidMount() {
      this.timerID = setInterval(
        () => this.tick(),
        1000
      )
    }
    
    2. 在组件卸载后清除计时器
    componentWillUnmount() {
      clearInterval(this.timerID)
    }
    
    3. 使用 this.setState() 来时刻更新组件 state
    class Clock extends React.Component {
      constructor(props) {
        super(props)
        this.state = { date: new Date() }
      }
      componentDidMount() {
        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>
        );
      }
    }
    RenderDOM.render(
      <Clock />,
      document.getElementById('root')
    )
    

    2 正确使用 State

    2.1 不要直接修改 state

    // wrong
    this.state.commit = 'Hello'
    // Correct
    this.setState({
      commit: 'Hello'
    })
    
    • 构造函数是唯一可以给 this.state 赋值的地方

    2.2 State 的更新可能是异步的

    • 出于性能考虑,react 可能会把多个 setState() 调用合并成一个调用

    • 要解决异步调用的问题,可以让 setState() 接收一个函数而不是一个对象,这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 作为第二个参数

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

    2.3 State 的更新会被合并

    2.4 数据是向下流动的

    • 任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件
  • 相关阅读:
    Swift
    iOS 拨打电话
    UI控件问题和XCode编译警告和错误解决方法集锦 (持续更新ing)
    让UIWebView弹出键盘上的按钮显示中文 (附效果图)
    启动app时全屏显示Default.png (附效果图)
    三种数据存储 (plist,NSUserDefaults存储,NSKeyedArchiver存模型方法)
    生成圆形头像 (附效果图)
    循环按钮,并且选中 (附效果图)
    leetcode 字符串分割对称
    leetcode merge-sorted-array/
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15410958.html
Copyright © 2011-2022 走看看