[翻译&摘抄] React 未来之函数式 setState

前端之家收集整理的这篇文章主要介绍了[翻译&摘抄] React 未来之函数式 setState前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_1@原文地址:Functional setState is the future of React
原文作者:Justice Mba
译文出自:掘金翻译计划
原文链接https://juejin.im/post/58cfcf6e44d9040068478fc6/
译者:reid3290
校对者:sunui,imink

温故知新

@H_403_1@1、React 是一个基于组件的 UI 库,组件基本上可以看作是一个接受某些属性然后返回 UI 元素的函数

@H_403_1@2、React 提供了一个用于管理 state 的特殊函数 —— setState()。

@H_403_1@3、setState() 的作用机制:你传递给它一个对象,该对象含有 state 中你想要更新的部分。

敲黑板,划重点

@H_403_1@setState() 不仅能接受一个对象,还能接受一个函数作为参数。函数接受该组件前一刻的 state 以及当前的 props 作为参数,计算和返回下一刻的 state。

this.setState(function (state,props) {
 return {
  score: state.score - 1
 }
});
@H_403_1@好奇宝宝要问了,这么做的目的是什么?

@H_403_1@理由是,state 的更新可能是异步的。

@H_403_1@React 在更新 State 的时候发生了什么?》
React 首先会将你传递给 setState() 的参数对象合并到当前 state 对象中,然后会启动所谓的 reconciliation,即创建一个新的 React Element tree(UI 层面的对象表示),和之前的 tree 作比较,基于你传递给 setState() 的对象找出发生的变化,最后更新 DOM。

@H_403_1@但是,React 不会仅仅简单地 “set-state”。因为涉及到的工作量比较大,调用 setState() 并不一定会即时更新 state 》React 可能会将多次 setState() 调用批处理(batch)为一次 state 的更新。

@H_403_1@也就是说,React 并不会按照 setState() 的调用顺序即时更新 state,而是首先会将所有对象合并到一起,然后仅用该对象进行一次 “set-state”。

@H_403_1@如果用户高频多次的setState,React 则会对这些操作进行批处理:即将每次调用 setState() 时传递给它的所有对象合并为一个对象,然后用这个对象去做真正的 setState()。

@H_403_1@那么就意味着,下面这个函数执行的结果会是1,而不是我们希望的3。

...

state = {score : 0};

// 多次 setState() 调用
increasescoreBy3 () {
    this.setState({score : this.state.score + 1});
    this.setState({score : this.state.score + 1});
    this.setState({score : this.state.score + 1});
}

...
@H_403_1@需要搞清楚的是,给 setState() 传递对象本身是没有问题的,问题出在当你想要基于之前的 state 计算出下一个 state 时还给 setState() 传递对象。这是不安全的!

@H_403_1@函数式 setState 来完成这样的任务

@H_403_1@当你编写函数式 setState 的时候,更新操作会形成一个任务队列,稍后会按其调用顺序依次执行。

@H_403_1@核心概念是,使用函数式 setState,你可以传递一个函数作为其参数,当执行该函数时,React 会将更新后的 state 复制一份并传递给它,这便起到了更新 state 的作用。基于上述机制,函数式 setState 便可基于前一刻的 state 来更新当前 state。

更进一步

@H_403_1@函数式 setState 的强大之处 —— 在组件类外部声明 state 的更新逻辑,然后在组件类内部调用之:

// 在组件类之外
function increasescore (state,props) {
  return {score : state.score + 1}
}

class User{
  ...

// 在组件类之内
  handleIncreasescore () {
    this.setState(increasescore)
  }

  ...
}
@H_403_1@这就叫做 declarative宣告式編程)!组件类不用再关心 state 该如何更新,它只须声明它想要的更新类型即可。

@H_403_1@设想如下场景:你有一些很复杂的组件,每个组件的 state 都由很多小的部分组成,基于 action 的不同,你必须更新 state 的不同部分,每一个更新函数都有很多行代码,并且这些逻辑都存在于组件内部。不过有了函数式 setState,再也不用面对上述问题了!

@H_403_1@并且,基于函数式 setState,你就可以将 state 的更新逻辑抽离为一个模块,然后在组件中引入和使用该模块。让代码显得小而美。

import {increasescore} from "../stateChanges";

class User{
  ...

  // 在组件类之内
  handleIncreasescore () {
    this.setState(increasescore)
}

  ...
}

猜你在找的React相关文章