React核心 -- React-Hooks

网友投稿 727 2022-05-30

hooks 存在的意义

hooks 之间的状态是独立的,有自己独立的上下文,不会出现混淆状态的情况

让函数有了状态管理

解决了 组件树不直观、类组件难维护、逻辑不易复用的问题

避免函数重复执行的副作用

应用场景

利用 hooks 取代生命周期函数

让组件有了状态

组件辅助函数

处理发送请求

存取数据

做好性能优化

hooks API

从 react 中引入

1. useState

给函数组件添加状态

初始化以及更新组件状态

const [count, setCount] = React.useState(0)

接收一个参数作为初始值,返回一个数组:第一个是状态变量,第二个是修改变量的函数

2. useEffect

副作用 hooks

给没有生命周期的组件,添加结束渲染的信号

注意:

render 之后执行的 hooks

第一个参数接收一个函数,在组件更新的时候执行

第二个参数接收一个数组,用来表示需要追踪的变量,依赖列表,只有依赖更新的时候才会更新内容

第一个参数的返回值,返回一个函数,在 useEffect 执行之前,都会先执行里面返回的函数

一般用于添加销毁事件,这样就能保证只添加一个

React.useEffect(() => { console.log('被调用了'); return () => { console.log('我要被卸载了'); } }, [count])

打印

3. useLayoutEffect

和 useEffect 很类似

它的作用是:在 DOM 更新完成之后执行某个操作

注意:

有 DOM 操作的副作用 hooks

在 DOM 更新之后执行

执行时机在 useEffect 之前,其他都和 useEffect 都相同

useEffect 执行时机在 render 之后

useLayoutEffect 执行时机在 DOM 更新之后

4. useMemo

作用:让组件中的函数跟随状态更新

注意:优化函数组件中的功能函数

为了避免由于其他状态更新导致的当前函数的被迫执行

第一个参数接收一个函数,第二个参数为数组的依赖列表,返回一个值

const getDoubleNum = useMemo(() => { console.log('ddd') return 2 * num }, [num])

作用:跟随状态更新执行

注意:

只有依赖项改变时才执行

useMemo( () => fn, deps) 相当于 useCallback(fn, deps)

不同点:

useCallback 返回的是一个函数,不再是值

useCallback 缓存的是一个函数,useMemo 缓存的是一个值,如果依赖不更新,返回的永远是缓存的那个函数

给子组件中传递 props 的时候,如果当前组件不更新,不会触发子组件的重新渲染

6. useRef

作用:长久保存数据

注意事项:

返回一个子元素索引,这个索引在整个生命周期中保持不变

对象发生改变时,不通知,属性变更不重新渲染

保存一个值,在整个生命周期中维持不变

重新赋值 ref.current 不会触发重新渲染

相当于创建一个额外的容器来存储数据,我们可以在外部拿到这个值

当我们通过正常的方式去获取计时器的 id 是无法获取的,需要通过 ref

React核心 -- React-Hooks

useEffect(() => { ref.current = setInterval(() => { setNum(num => num + 1) }, 400) }, []) useEffect(() => { if (num > 10) { console.log('到十了'); clearInterval(ref.current) } }, [num])

7. useContext

作用:带着子组件渲染

注意:

上层数据发生改变,肯定会触发重新渲染

我们需要引入 useContext 和 createContext 两个内容

通过 createContext 创建一个 Context 句柄

通过 Provider 确定数据共享范围

通过 value 来分发数据

在子组件中,通过 useContext 来获取数据

import React, { useContext, createContext } from 'react' const Context = createContext(null) export default function Hook() { const [num, setNum] = React.useState(1) return (

这是一个函数组件 - {num} // 确定范围

) } function Item1() { const num = useContext(Context) return
子组件1 {num}
} function Item2() { const num = useContext(Context) return
子组件2 {num}
}

8. useReducer

作用:去其他地方借资源

注意:函数组件的 Redux 的操作

创建数据仓库 store 和管理者 reducer

通过 useReducer(store,dispatch) 来获取 state 和 dispatch

const store = { num: 10 } const reducer = (state, action) => { switch (action.type) { case "": return default: return } } const [state, dispatch] = useReducer(reducer, store)

通过 dispatch 去派发 action

9. 自定义 hooks

放在 utils 文件夹中,以 use 开头命名

例如:模拟数据请求的 Hooks

import React, { useState, useEffect } from "react"; function useLoadData() { const [num, setNum] = useState(1); useEffect(() => { setTimeout(() => { setNum(2); }, 1000); }, []); return [num, setNum]; } export default useLoadData;

减少代码耦合

我们希望 reducer 能让每个组件来使用,我们自己写一个 hooks

自定义一个自己的 LocalReducer

import React, { useReducer } from "react"; const store = { num: 1210 }; const reducer = (state, action) => { switch (action.type) { case "num": return { ...state, num: action.num }; default: return { ...state }; } }; function useLocalReducer() { const [state, dispatch] = useReducer(reducer, store); return [state, dispatch]; } export default useLocalReducer;

引入 react 和自己需要的 hook

创建自己的hook函数

返回一个数组,数组中第一个内容是数据,第二个是修改数据的函数

暴露自定义 hook 函数出去

引入自己的业务组件

React 数据结构 渲染

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Java】【JVM基础】详解class文件与JVM的关系
下一篇:强大!Nginx 配置在线一键生成“神器”
相关文章