1. React中用过哪些hooks
- useState和useReducer: 做组件状态的维护,当state是基础类型、状态变更逻辑比较简单且在本组件中完成时使用useState,否则使用useReducer,useState对应修改state的操作时setState,useReducer接收state变更的逻辑以及初始state,对状态的修改是dispatch,如果状态会被子组件修改,可配合useContext使用
- useEffect: 它是在依赖项变化后执行回调函数,在下一轮useEffect执行前执行回调函数的返回值,所以可以用来做页面渲染结束后或某些依赖项变化后,数据的请求,对于不相关的处理可以使用多个useEffect来降低耦合
- createContext+useContext: 用它们来做跨组件数据传递,使用createContext创建context,使用这个context的Provider组件包裹公共父组件,Consumer组件包裹需要使用数据的子组件,并在子组件中使用useContext拿数据
- useRef: 创建一个在组件生命周期里都不变的对象,通常用它保存一个值,保存在内部的current变量中,可以用它来做子组件的引用,方便父组件使用子组件数据和方法
- useMemo、useCallback、useMemo: 计算过程比较耗时的结果使用useMemo包裹,来避免组件更新时的重复计算,传递给子组件的对象或函数使用useMemo或useCallBack包裹,来避免不必要的渲染。(类组件中可以通过继承React.PureComponent或修改生命周期方法shouldComponentUpdate做类似实现)
- 自定义hooks:
/**
* 功能:通过hooks的方式为方法添加防抖,用闭包维护目标函数,以及目标函数是否正在等待
* @params {Function} fn: 目标函数
* @parmas {number} ms: 防抖时间
* @parmas {Array} dep: 依赖数组,添加这个是因为在React中hooks定义在组件内部,组件重新渲染时hooks会再次执行,需要借助useCallback+依赖数组跳过不必要的更新
*/
const useDebounce = (fn, ms, dep = []) => {
console.log('initial debounce');
// 使用useRef目的:保证维护的变量不会在useDebounce重新调用时再次初始化
const { current } = useRef({ fn, timer: null });
// 使用useEffect目的:当fn传入新函数时更新闭包中保存的函数,下次调用就是用新的函数
// 所以,传入的函数建议使用useCallback缓存
// 不清楚:当不带花括号时会一直更新 useEffect(() => current.fn = fn, [fn]);
useEffect(() => { current.fn = fn }, [fn]);
// 防抖逻辑主体,如果有正在执行的就清理掉,开始新的并将新的执行记录到闭包中
const res = useCallback((...args) => {
current.timer &&