React学习之State与生命周期基友情四

我先拉拉对React-DOM输出那篇文章的知识点,从那篇文章中得知,至今为止我们只会用ReactDOM.render()去更改覆盖数据来进行视图更新,然而还是在时间的控制下进行变化。

现在我们要做的就是让组件自己跑起来

何为state?

State是一种类似于props的东西,属于组件元素的属性,但是它是私有的,并且完全被组件所控制,所以State只会存在于组件中,不是组件的话,可以走开了,并且它是可变的,而props这货是不可变的,这也是为什么State可以取代props用来实时更新视图的原因。

当然,State只是属于类组件的,不是函数式的组件的,它被作为一个类的特性与类组件绑定起来,所以函数式组件要使用State还需要转换为类组件,不然会很尴尬。

转换的步骤如下:

  1. 创建一个ES6的类继承于React.Component
  2. 增加一个简单的空函数render()
  3. .将我们的函数式组件的主体放到render()函数中
  4. render中将props替换为this.props
  5. 删除原先函数式组件的声明

其实上述步骤大家都懂,不多说了。

1.给类组件增加State状态标记数据

由于我们的props定义以后存在不可扩展和不可变性,所以用state来取代props进行数据更新变化,我们将一个数据要变为可变的,或者说想让props上的数据可变,实时更新,可以通过一下两步:

1.在render函数中,将this.props.date替换为this.state.date,如下:

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

2.为类组件增加一个constructor函数去初始化this.state这个属性,如下:

class Cl 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.toString()}.</h2>
      </div>
    );
  }
}

这里我们通过superprops初始化构造函数

constructor(props) { super(props); this.state = {date: new Date()};
}

2.为类组件增加生命周期方法控制

我们将通过React挂载和卸载两个功能来实现一次Render即可更新视图,这两种功能的表现形式分别为componentDidMountcomponentWillUnmount,具体实例如下:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
  }
  componentWillUnmount() {
  }
  render() {
    return (
      <div>
        <h1>Hello,world!</h1>
        <h2>It is {this.state.date.toString()}.</h2>
      </div>
    );
  }
}

componentDidMountcomponentWillUnmount,这两个方法被俗称为生命挂钩(自己取得,代表着跟组件的创建摧毁有关),componentDidMount函数会在我们render一个组件元素渲染到视图上后运行,在这里我们可以建立一个定时器,如下:

componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),1000
    );
  }

componentWillUnmount则是在对象摧毁时执行,一般用来摧毁我们在componentDidMount中创建的定时器

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

然后我们的更新就完成了,如下:

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.toString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,document.getElementById('root')
);

看到这些代码,大家就可以知道state是实时更新的,如此来更新界面,而去掉了反复用render处理。

这里我们整理一下,上面这份代码的函数调用步骤和实现方式。

  1. 当我们的ReactDOM.render()处理到了Clock类组件JSX时,React会调用Clock组件的构造函数constructor,用于给this.state数据进行初始化

  2. React会调用Clockrender方法,让React通过这个函数知道怎么将数据渲染到视图中,然后将数据渲染到DOM

  3. ReactClock组件的数据内嵌到DOM中后,React就会调用componentDidMount()生命周期钩,就componentDidMount中的代码而言,React会告诉浏览器,Clock类组件需要设定一个定时器,每秒钟调用一次tick

  4. 浏览器会每一秒钟调用tick函数,在tick中有一个setState函数,这个的作用就是告诉Reactstate对象被改变了,然后会自动调用render函数进行重新渲染,也就是说依旧是调用render,在上面的代码中,React自己隐性调用的,而不是我们显性调用它。

  5. 如果Clock组件从DOM中移除的话,React会调用componentWillUnmount()来将这个定时器给摧毁掉

3.请正确的使用state状态标记属性

很明显,state是一个属性,也可以看成一个对象,那么一定可以进行如下设置:

this.state.date = new Date();

但是这样会非常费神,而且会造成代码冗余,为什么呢,感同身受的就是为一个标签设置css样式,如果没有jquerycss函数,或者是你没有写过一个比较实用的css处理函数,会发现一个非常懵逼的问题,就是属性设置写的代码能亮瞎你的眼,简直丑的一比。

所以我们这里要用jquery.css函数的使用方法为state进行设置。

this.setState({date: new Date()});

4.state更新可能会很飘

为何这么说呢?但我们一起使用多个setStatestate的状态就会有点飞。
就是说state状态对象更新可能是异步的,不是同步的。

当用如下这种形式:就会出现异步情况:

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

上述的操作,如果出现多条的话,会造成计算失误,也就是说多个语句执行的顺序会不同从而造成结果错误。

解决方案

用函数来代替对象处理:

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

这个函数格式是固定的,必须第一个参数是state的前一个状态,第二个参数是属性对象props,这两个对象setState会自动传递到函数中去,同时,这些函数在setState中的执行是同步的,从而解决了异步问题。

5.确保底层组件的透明性

组件之间耦合性越低越好,换句话说,不管是父组件还是子组件,都不知道对方是个什么鬼,不知道对方是函数式组件还是类组件,每一个组件都自我封装,只留下一个借口进行对外交互,同时只有父组件知道子组件会干啥,需要传递什么东西给子组件,而子组件却不知道父组件干了什么,可能传递了props,或者state又或是直接明了的数据,他只进行处理数据,不管数据到底怎么来的。

上述这种透明形式,官方成为自上而下,单向数据流,上层只能控制下一层的数据,无法对上层产生任何影响。

简单地说,水往低处流。

此篇博客设计的ES6的箭头函数如果大家不是很明白可以参考官方网站,当然之后,个人可能会一套ES6学习的博客,敬请期待

下一篇会将React的事件处理机制

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom