(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩

原文地点:https://medium.com/@ryardley/…

译文:染陌 (Github

译文地点:https://github.com/answershuto/Blog

转载请有名出处

我是一位hooks API的忠厚粉丝,然则它对你的运用会有一些新鲜的束缚,所以我在本文中运用一个模子来把道理展现给那些想去运用新的API却难以明白它的划定规矩的人。

正告:Hooks 还处于试验阶段

本文提到的 Hooks API 还处于试验阶段,假如你须要的是稳固的 React API 文档,可以从这里找到。

解密 Hooks 的事变体式格局

我发明一些同砚苦苦思索新的 Hooks API 中的“魔法”,所以我盘算尝试着去解释一下,最少从表层动身,它是怎样事变的。

Hooks 的划定规矩

React 中心团队在Hooks的提案中提出了两个在你运用Hooks的过程当中必需去恪守的主要划定规矩。

  • 请不要在轮回、前提或许嵌套函数中挪用 Hooks
  • 都有在 React 函数中才去挪用 Hooks

后者我以为是不言而喻的,你须要用函数的体式格局把行动与组件关联起来才能把行动添加到组件。

然则关于前者,我以为它会让人发作疑心,由于如许运用 API 编程好像显得不那末天然,但这就是我本日要套索的内容。

Hooks 的状况治理都是依靠数组的

为了让人人发作一个更清楚的模子,让我们来看一下 Hooks 的简朴完成多是什么模样。

须要注重的是,这部分内容只是 API 的一种可以完成要领,以便读者更好地趣明白它。它并非 API 现实在内部的事变体式格局,而且它只是一个提案,在未来都邑有可以发作变化。

我们应当怎样完成“useState()”呢?

让我们经由过程一个例子来明白状况多是怎样事变的。

起首让我们从一个组件最先:

代码地点

/* 译:https://github.com/answershuto */
function RenderFunctionComponent() {
  const [firstName, setFirstName] = useState("Rudi");
  const [lastName, setLastName] = useState("Yardley");

  return (
    <Button onClick={() => setFirstName("Fred")}>Fred</Button>
  );
}

Hooks API 背地的头脑是你可以将一个 setter 函数经由过程 Hook 函数的第二个参数返回,用该函数来掌握 Hook 治理的壮体。

所以 React 能用这个做什么呢?

起首让我们解释一下它在 React 内部是怎样事变的。在实行上下文去衬着一个特别组件的时刻,下面这些步骤会被实行。这意味着,数据的存储是自力于组件以外的。该状况不能与其他组件同享,然则它具有一个自力的作用域,在该作用域须要被衬着时读取数据。

(1)初始化

建立两个空数组“setters”与“state”

设置指针“cursor”为 0

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

(2)初次衬着

初次实行组件函数

每当 useState() 被挪用时,假如它是初次衬着,它会经由过程 push 将一个 setter 要领(绑定了指针“cursor”位置)放进 setters 数组中,同时,也会将另一个对应的状况放进 state 数组中去。

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

(3)后续衬着

每次的后续衬着都邑重置指针“cursor”的位置,并会从每一个数组中读取对应的值。

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

(4)处置惩罚事宜

每一个 setter 都邑有一个对应的指针位置的援用,因而当触发任何 setter 挪用的时刻都邑触发去转变状况数组中的对应的值。

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

以及底层的完成

这是一段示例代码:

代码地点

let state = [];
let setters = [];
let firstRun = true;
let cursor = 0;

function createSetter(cursor) {
  return function setterWithCursor(newVal) {
    state[cursor] = newVal;
  };
}

/* 译:https://github.com/answershuto */
// This is the pseudocode for the useState helper
export function useState(initVal) {
  if (firstRun) {
    state.push(initVal);
    setters.push(createSetter(cursor));
    firstRun = false;
  }

  const setter = setters[cursor];
  const value = state[cursor];

  cursor++;
  return [value, setter];
}

/* 译:https://github.com/answershuto */
// Our component code that uses hooks
function RenderFunctionComponent() {
  const [firstName, setFirstName] = useState("Rudi"); // cursor: 0
  const [lastName, setLastName] = useState("Yardley"); // cursor: 1

  return (
    <div>
      <Button onClick={() => setFirstName("Richard")}>Richard</Button>
      <Button onClick={() => setFirstName("Fred")}>Fred</Button>
    </div>
  );
}

// This is sort of simulating Reacts rendering cycle
function MyComponent() {
  cursor = 0; // resetting the cursor
  return <RenderFunctionComponent />; // render
}

console.log(state); // Pre-render: []
MyComponent();
console.log(state); // First-render: ['Rudi', 'Yardley']
MyComponent();
console.log(state); // Subsequent-render: ['Rudi', 'Yardley']

// click the 'Fred' button

console.log(state); // After-click: ['Fred', 'Yardley']

为什么说递次很主要呢?

假如我们基于一些外部前提或是说组件的状况去转变 Hooks 在衬着周期的递次,那会发作什么呢?

让我们做一些 React 团队制止去做的事变。

代码地点

let firstRender = true;

function RenderFunctionComponent() {
  let initName;
  
  if(firstRender){
    [initName] = useState("Rudi");
    firstRender = false;
  }
  const [firstName, setFirstName] = useState(initName);
  const [lastName, setLastName] = useState("Yardley");

  return (
    <Button onClick={() => setFirstName("Fred")}>Fred</Button>
  );
}

我们在前提语句中挪用了 useState 函数,让我们看看它对悉数体系形成的损坏。

蹩脚组件的初次衬着

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

到此为止,我们的变量 firstName 与 lastName 照旧包含了准确的数据,让我们继承去看一下第二次衬着会发作什么事变。

蹩脚的第二次衬着

《(译)React hooks:它不是一种魔法,只是一个数组——运用图表揭秘提案划定规矩》

如今 firstName 与 lastName 这两个变量悉数被设置为“Rudi”,与我们现实的存储状况不符。

这个例子的用法显然是不准确的,然则它让我们知道了为什么我们必需运用 React 团队划定的划定规矩去运用 Hooks。

React 团队制订了这个划定规矩,是由于假如不遵照这套划定规矩去运用 Hooks API会致使数据有题目。

思索 Hooks 保护了一些列的数组,所以你不该当去违背这些划定规矩

所以你如今应当消灭为什么你不该当在前提语句或许轮回语句中运用 Hooks 了。由于我们保护了一个指针“cursor”指向一个数组,假如你转变了 render 函数内部的挪用递次,那末这个指针“cursor”将不会婚配到准确的数据,你的挪用也将不会指向准确的数据或句柄。

因而,有一个窍门就是你须要思索 Hooks 作为一组须要一个婚配一致的指针“cursor”去治理的数组(染陌译)。假如做到了这一点,那末采纳任何的写法它都可以一般事变。

总结

愿望经由过程上述的解说,我已给人人建立了一个关于 Hooks 的越发清楚的头脑模子,以此可以去思索新的 Hooks API 底层究竟做了什么事变。请记着,它真正的代价在于可以关注点群集在一起,同时警惕它的递次,那运用 Hooks API 会很高的报答。

Hooks 是 React 组件的一个很有效的插件,这也左证了为什么人人为什么对此觉得云云高兴。假如你脑海中形成了我上述的这类头脑模子,把这类状况作为一组数组的存在,那末你就会发明在运用中不会突破它的划定规矩。

我愿望未来再去研究一下 useEffects useEffects 要领,并尝试将其与 React 的生命周期举行比较。

这篇文章是一篇在线文档,假如你想要介入孝敬或许有任何有误的处所,迎接联络我。

你可以在 Twitter 上面 fllow 我(Rudi Yardley)或许在Github找到我。

染陌 译:https://github.com/answershuto

    原文作者:染陌同学
    原文地址: https://segmentfault.com/a/1190000017136457
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞