希沃ENOW大前端javascript
公司官网:CVTE(广州视源股份)css
团队:CVTE旗下将来教育希沃软件平台中心enow团队html
本文做者:前端
在听到这么一个问题的时候,首先脑海中整体思路是这样子的:java
Hook
的基本概念Hook
进行复用逻辑的封装Hook
的最佳实践与工做原理Hook
底层原理思想Reack Hook
思想Hook
是 React 16.8
的新增特性。它可让你在不编写 class
的状况下使用 state
以及其余的 React
特性。React
官方提供了经常使用的StateHook
和EffectHook
分别用以管理函数式组件状态和反作用。(React Hook官方介绍)。react
除了官方提供的StateHook和EffectHook外,咱们能够本身将经常使用的组件逻辑抽取到可重用的函数中,该函数须以React约定的形式来命名与使用,用以共享组件逻辑。git
经过一个简单的例子来看一下 好比咱们须要在拿到某个数据后设置页面标题,并且须要在各个页面里面使用github
import React, { useState, useEffect } from 'react';
export default function App() {
// 正常咱们这样子实现
const [title, setTitle] = useState('默认标题')
useEffect(() => {
document.title = title;
}, [title]);
const onTitleChange = (event) => {
setTitle(event.target.value);
}
return (<div> <h2>{title}</h2> <input type="text" onInput={onTitleChange}/> </div>)
}
复制代码
export function useSetPageTitle (initTitle) {
const [title, setTitle] = useState(initTitle || '默认标题');
useEffect(() => {
document.title = title;
}, [title]);
return [title, setTitle]
}
复制代码
import { useSetPageTitle } from '../App';
export default function Chirld() {
// 这里使用刚才写自定义Hook
const [title, setTitle] = useSetPageTitle();
return (<div> <h2>{title}</h2> <input type="text" onInput={onTitleChange}/> </div>>)
}
复制代码
这样子一个自定义的hook
就成型了,是否是瞬间感受逼格提升了,原来我也能够写个这么高大上的自定义Hook
,哈哈哈。npm
聪明的大家必定发现了下面的特色数组
Hook
必须以 use
开头上面的例子中使用【useSetPageTitle】
。不遵循的话,因为没法判断某个函数是否包含对其内部 Hook
的调用,React 将没法自动检查你的 Hook
是否违反了 Hook
的规则。
Hook
可自由搭配其余hook
使用你能够自由使用其余内部Hook
和其余自定义Hook
.上面演示例子中使用useState
和useEffect
.
这样作是为了确保 Hook
在每一次渲染中都按照一样的顺序被调用。若是不是最顶层会致使状态或者执行方法出错进而致使BUG
。
当state='A'
条件知足时执行调用Hook
顺序是正常,当后续渲染条件不知足时,则React
调用Hook
顺序出错,则会致使方法和状态逻辑执行出错。
import React, { useState, useEffect } from 'react';
import './App.css';
import { useSetPageTitle } from './hooks';
export default function App() {
const [state, setState] = useState('A');
// 反例
if (state === 'A') {
useEffect(() => {
console.log('只执行一次')
}, [state]);
}
useState({});
useEffect(() => {
// 获取数据
}, []);
useState({});
console.log(title)
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
复制代码
import React, { useState, useEffect } from 'react';
export default function App() {
const [state, setState] = useState('A');
useEffect(() => {
if (state === 'A') {
console.log('执行相应的逻辑')
}
}, [state]);
useState({});
useEffect(() => {
// 获取数据
}, []);
useState({});
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
复制代码
为了不出错咱们可使用ESLint插件来检测强制执行这些规则。 另外,亲测React官方提供的create-react-app @3.x与@4.x在eject后已经集成了插件
eslint-plugin-react-hooks
复制代码
// 你的 ESLint 配置
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error", // 检查 Hook 的规则
"react-hooks/exhaustive-deps": "warn" // 检查 effect 的依赖
}
}
复制代码
自定义 Hook
解决了之前在React
组件中没法灵活共享逻辑的问题。那么业务开发中可建立各类的自定义Hook
,公共辅助函数、状态复用、逻辑复用、效果复用、操做复用、生命周期模拟以及多种组合复用等只有想不到,相信很难有这么聪明的大家作不到的场景实现。
下面举几个简单栗子,抛砖引玉
useMount
模拟生命周期componentDidMount
import React, { useState, useEffect } from 'react';
function useMount (fn) {
useEffect(() => {
fn();
}, []);
}
export default function App() {
useMount(() => {
// 你的逻辑
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
复制代码
useEffect
返回函数是销毁才调用的机制来模拟unmount
function useUnmount (fn) {
useEffect(() => {
return () => {
fn();
}
}, []);
}
export default function App() {
useUnmount(() => {
console.log('销毁组件时输出')
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
复制代码
import React, { useState, useEffect } from 'react';
function useOnResize (fn) {
useEffect(() => {
window.addEventListener('resize',fn);
return () => {
window.removeEventListener('resize',fn)
}
}, []);
}
export default function App() {
useOnResize(() => {
console.log(document.body.clientWidth)
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
复制代码
由蚂蚁 umi 团队、淘系 ice 团队以及阿里体育团队共同建设的 React Hooks 工具库ahooks
Set of a helpful hooks, for different specific to some primitives types state changing helpers.
可使建立弹窗,提示,菜单变得很是容易,提供了建立DOM层次以外的元素的功能
用于发起Http请求的优秀Hook
发现更多优秀Hook库可在下面评论贴上,整一个优秀Hooks库的集合。
笔者并无实际看过React源码,仅看过一些React Hook工做原理的文章。 这里抛转引玉,看过几个比较好来分享。欢迎留言更多优秀实践和原理剖析。
迎(bu)接(yao)新(geng)轮(xin)子(le),向(biao)着(shi)新(xue)轮(bu)子(dong)前(le)进