TL;DR
一句话总结 React Hooks 就是在 react 函数组件中,也可以使用类组件(classes components)的 state 和 组件生命周期,而不需要在 mixin、 函数组件、HOC组件和 render props 之间来回切换,使得函数组件的功能更加实在,更加方便我们在业务中实现业务逻辑代码的分离和组件的复用。
本文将从以下几个方面介绍 hooks
Hooks 在解决什么问题 Hooks 的 api 介绍 和如何使用 hooks Hooks 是怎么实现的
💡Hooks 在解决什么问题
React 一直在解决一个问题,如何实现分离业务逻辑代码,实现组件内部相关业务逻辑的复用。
一般情况下,我们都是通过组件和自上而下传递的数据流将我们页面上的大型UI组织成为独立的小型UI,实现组件的重用。但是我们经常遇到很难侵入一个复杂的组件中实现重用,因为组件的逻辑是有状态的,无法提取到函数组件当中。这在处理动画和表单的时候,尤其常见,当我们在组件中连接外部的数据源,然后希望在组件中执行更多其他的操作的时候,我们就会把组件搞得特别糟糕:
- 难以重用和共享组件中的与状态相关的逻辑,造成产生很多巨大的组件
 - 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 localstate 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面。
 - 复杂的模式,如渲染道具和高阶组件。
 - 由于业务变动,函数组件不得不改为类组件。
 
这时候,Hooks就派上用场了。 Hooks 允许我们将组件内部的逻辑,组织成为一个可复用的隔离模块。
借用 @Sunil Pai 的两张图来说明这个问题:
image.png
image.png
从 React Hooks 中体验出来的是 React 的哲学在组件内部的实现,以前我们只在组件和组件直接体现 React 的哲学,就是清晰明确的数据流和组成形式。既可以复用组件内的逻辑,也不会出现 HOC 带来的层层嵌套,更加不会出现 image.png
初始化:两个空数组,Cursor为0
2) 首次渲染
首次运行组件功能。
每次useState()调用,当在第一次运行时,将setter函数(绑定到光标位置)推送到setter数组,然后将某个状态推送到state数组。
image.png
第一次渲染:作为光标增量写入数组的项目。
3) 后续渲染
每个后续渲染都会重置光标,并且只从每个数组中读取这些值。
image.png
后续渲染:从数组中读取的项目为光标增量
4) 事件处理
每个setter都有一个对它的光标位置的引用,因此通过触发对任何setter的调用,它将改变状态数组中该位置的状态值。
image.png
Setters“记住”他们的索引并根据它设置内存。
通过伪代码实现 useState 功能
这是一个演示实现的代码示例:
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]; }  // 模拟使用useState 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>   ); }  // 模拟Reacts渲染周期 function MyComponent() {   cursor = 0; //  重置光标的位置   return <RenderFunctionComponent />; // render }  console.log(state); // Pre-render: [] MyComponent(); console.log(state); // 首次渲染: ['Rudi', 'Yardley'] MyComponent(); console.log(state); // 后续渲染: ['Rudi', 'Yardley']  // 点击'Fred' 按钮   console.log(state); // 点击后: ['Fred', 'Yardley']总结
Hooks 还处于早期阶段,但是给我们复用组件的逻辑提供了一个很好的思路,大家可以在 react-16.7.0-alpha.0 中体验。
此文已由作者授权腾讯云+社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!
