10分钟教你手写8个常用的自定义hooks
2020/2/29 11:15:18
本文主要是介绍10分钟教你手写8个常用的自定义hooks,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。本文是一篇以实战为主的文章,主要讲解实际项目中如何使用hooks以及一些最佳实践,不会一步步再介绍一遍react hooks的由来和基本使用,因为写hooks的文章很多,而且官网对于react hooks的介绍也很详细,所以大家不熟悉的可以看一遍官网。
你将收获
- react hooks核心API使用以及注意事项
- 实现一个小型redux
- 实现自定义的useState
- 实现自定义的useDebounce
- 实现自定义的useThrottle
- 实现自定义useTitle
- 实现自定义的useUpdate
- 实现自定义的useScroll
- 实现自定义的useMouse
- 实现自定义的createBreakpoint
正文
1. react hooks核心API使用注意事项
笔者在项目中常用的hooks主要有useState, useEffect,useCallback,useMemo,useRef。当然像useReducer, useContext, createContext这些钩子在H5游戏中也会使用,因为不需要维护错综复杂的状态,所以我们完全可以由上述三个api构建一个自己的小型redux(后面会介绍如何实现小型的redux)来处理全局状态,但是对于企业复杂项目来说,我们使用redux及其生态会更加高效一些。
我们在使用hooks和函数组件编写我们的组件时,第一个要考虑的就是渲染性能,我们知道如果在不做任何处理时,我们在函数组件中使用setState都会导致组件内部重新渲染,一个比较典型的场景:
当我们在容器组件手动更新了任何state时,容器内部的各个子组件都会重新渲染,为了避免这种情况出现,我们一般都会使用memo将函数组件包裹,来达到class组件的pureComponent的效果:import React, { memo, useState, useEffect } from 'react' const A = (props) => { console.log('A1') useEffect(() => { console.log('A2') }) return <div>A</div> } const B = memo((props) => { console.log('B1') useEffect(() => { console.log('B2') }) return <div>B</div> }) const Home = (props) => { const [a, setA] = useState(0) useEffect(() => { console.log('start') setA(1) }, []) return <div><A n={a} /><B /></div> } 复制代码
当我们将B用memo包裹后,状态a的更新将不会导致B组件重新渲染。其实仅仅优化这一点还远远不够的,比如说我们子组件用到了容器组件的某个变量或者函数,那么当容器内部的state更新之后,这些变量和函数都会重新赋值,这样就会导致即使子组件使用了memo包裹也还是会重新渲染,那么这个时候我们就需要使用useMemo和useCallback了。
useMemo可以帮我们将变量缓存起来,useCallback可以缓存回调函数,它们的第二个参数和useEffect一样,是一个依赖项数组,通过配置依赖项数组来决定是否更新。
import React, { memo, useState, useEffect, useMemo } from 'react' const Home = (props) => { const [a, setA] = useState(0) const [b, setB] = useState(0) useEffect(() => { setA(1) }, []) const add = useCallback(() => { console.log('b', b) }, [b]) const name = useMemo(() => { return b + 'xuxi' }, [b]) return <div><A n={a} /><B add={add} name={name} /></div> } 复制代码
此时a更新后B组件不会再重新渲染。以上几个优化步骤主要是用来优化组件的渲染性能,我们平时还会涉及到获取组件dom和使用内部闭包变量的情景,这个时候我们就可以使用useRef。
useRef返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
function AutoFocusIpt() { const inputEl = useRef(null); const useEffect(() => { // `current` 指向已挂载到 DOM 上的文本输入元素 inputEl.current.focus(); }, []); return ( <> <input ref={inputEl} type="text" /> </> ); } 复制代码
除了以上应用场景外,我们还可以利用它来实现class组件的setState的功能,具体实现后面会有介绍。
2. 实现一个小型redux
实现redux我们会利用之前说的useReducer, useContext, createContext这三个api,至于如何实现redux,其实网上也有很多实现方式,这里笔者写一个demo供大家参考:
// actionType.js const actionType = { INSREMENT: 'INSREMENT', DECREMENT: 'DECREMENT', RESET: 'RESET' } export default actionType // actions.js import actionType from './actionType' const add = (num) => ({ type
这篇关于10分钟教你手写8个常用的自定义hooks的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南