【React】hooks的原理

https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e

参考了这篇文章,对hooks的实现有初步的了解,具体的还是得研究一下官方的,这篇文章用了一个简单的方式和代码去介绍React的hooks是如何实现的。

平时我们经常使用的Hook是useState()

通过其的一个简单实例

function RenderFunctionComponent() {
  const [firstName, setFirstName] = useState("Rudi");
  const [lastName, setLastName] = useState("Yardley");

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

我们使用useState()通常的代码的,一般最好奇的事情就是,为什么是 

const [key, setkey] = useState()

我们更新值的话都是通过

setKey(new value)

去更新的,所以这个时候就会很懵懂其背后是怎么实现更新的。

下面借鉴上述博客中的图去理解

(1)初始化

创建两个空的数组 state 和 setters, 同时讲指针设置为0

(2)第一次渲染

在第一次运行时,会将setter函数放入setters数组,同时会记录指针现在的位置,然后讲对应的state放入state数组。

(3)后面的渲染

初始化过后,指针会初始化到0,这样做是为了可以讲每个值从数据中读出

(4)请求的处理

每一个setter对游标位置都有一个引用,所以更改state的值就是通过去调用setter从而触发其对应数组在对应位置的值

在这里其实对setters函数的作用就有一点明白了,但是这里仅仅用于理解,背后的数据结构设计应该没那么简单。

最主要可以理解的点就是state的值是不断变化的,那么其就不能固定去寻找了(要做应该也行,可能在数据结构方面的开销会更大吧,不然如果可以用一个map解决开发团队绝不会用得那么麻烦),通过一个setter函数,首先名字是固定的,其实通过指针(游标)去确定对应的state值的位置,并将其更新。

通过一段简单的代码去理解

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

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

// 模仿一个useState的函数
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];
}

// 使用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>
  );
}

// 这是一种模拟的渲染周期
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']

在这个模拟的过程中,不难发现,每次都是重新去变量setter和state的数组,虽然这个仅仅只是为了更好的理解,但是在渲染方面还是有点值得思路的,就是按道理应该每次重新渲染不是全部渲染,应该是局部的,这个感觉涉及到内部的匹配算法了。

但是通过上面,可以初步理解整一个过程其是大概怎么实现,同时在写代码的时候不会觉得很奇怪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值