zoukankan      html  css  js  c++  java
  • Hook

    它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。无状态组件的也可以使用状态了

    Hook(钩子) 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数

    基础 Hook

    • useState

    let [ 数据,修改数据的函数]= useState (数据的初始值)

    修改的时候,用的地址传递,没新创建对象或者数组,没深克隆
    hook的useState返回的方法是异步的

    useState 方法的返回值是什么? 
    返回值为:当前 state 以及更新 state 的函数

    let [type,setType] = useState(1)//()里的是初始值,type === 1
    type:要修改那一个值
    setType:修改这个值的函数
    

    • useEffect

    就是一个 Effect Hook,给函数组件增加了操作副作用(effect)(在 React 组件中执行过数据获取、订阅或者手动修改过 DOM)的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API

    为什么在组件内部调用 useEffect?

    将 useEffect 放在组件内部让我们可以在 effect 中直接访问 count state 变量(或其他 props)

    useEffect 会在每次渲染后都执行吗?

    是的,默认情况下,它在第一次渲染之后和每次更新之后都会执行。
    React 保证了每次运行 effect 的同时,DOM 都已经更新完毕

    传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。事实上这正是我们可以在 effect 中获取最新的 count 的值,而不用担心其过期的原因。每次我们重新渲染,都会生成新的 effect,替换掉之前的'

    需要清除的 effect

    为什么要在 effect 中返回一个函数?

    这是 effect 可选的清除机制。每个 effect 都可以返回一个清除函数。如此可以将添加和移除订阅的逻辑放在一起。它们都属于 effect 的一部分。

    React 何时清除 effect?

    React 会在组件卸载的时候执行清除操作。正如之前学到的,effect 在每次渲染的时候都会执行。这就是为什么 React 会在执行当前 effect 之前对上一个 effect 进行清除
    可以使用多个 effec
    react 将按照 effect 声明的顺序依次调用组件中的每一个 effect。

    HOOK规则:

    Hook 需要在我们组件的最顶层调用,因为hook是按顺序执行的,不放在外边,容易引起bug,如下案例:
    注意:如果使用了提供的 lint 插件,就无需担心此问题
    eslint-plugin-react-hooks:https://www.npmjs.com/package/eslint-plugin-react-hooks

    优化
    利用useEffect的第二个参数优化,如果count变化了,才会执行这个useEffect

    通过跳过 Effect 进行性能优化

    1)、如果你要使用此优化方式,请确保数组中包含了所有外部作用域中会随时间变化并且在 effect 中使用的变量,否则你的代码会引用到先前渲染中的旧变量。
    2)、如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。

    • useContext

    const value = useContext(MyContext);

    方法一:将共同的状态 state 和 dispatch 通过 React.createContext存入到context中,再通过useContext API获取context中的内容。
    React.createContext创建context对象=>context.Provider传递数据(可以是仓库) =>useContext(context)接收context对象(数据)

    方法二:直接采用React Context API。
    React.createContext创建context对象=>context.Provider传递数据=>context.Consumer接收数据

    方法一:

    reducer.js

    count.js

    子组件中只需要通过useContext API获取这个状态

    index.js

    方法二



    1、接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。useContext 的参数必须是 context 对象本身

    2、调用了 useContext 的组件总会在 context 值变化时重新渲染。如果重渲染组件的开销较大,你可以 通过使用 memoization 来优化

    额外的 Hook

    • useReducer

    const [state, dispatch] = useReducer(reducer, initialArg, init);

    指定初始 state两种方式

    1、将初始 state 作为第二个参数传入 useReducer 是最简单的方法:

    2、惰性初始化
    将 init 函数作为 useReducer 的第三个参数传入,这样初始 state 将被设置为 init(initialArg),
    这么做可以将用于计算 state 的逻辑提取到 reducer 外部,这也为将来对重置 state 的 action 做处理提供了便利

    跳过 dispatch

    如果 Reducer Hook 的返回值与当前 state 相同,React 将跳过子组件的渲染及副作用的执行。(React 使用 Object.is 比较算法 来比较 state。)
    需要注意的是,React 可能仍需要在跳过渲染前再次渲染该组件。不过由于 React 不会对组件树的“深层”节点进行不必要的渲染,所以大可不必担心。如果你在渲染期间执行了高开销的计算,则可以使用 useMemo 来进行优化。

    • useCallback

    返回一个 memoized 回调函数。把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子组件时,它将非常有用。
    如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值

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

    • useMemo

    tip

    1)、传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo

    2)、你可以把 useMemo 作为性能优化的手段,但不要把它当成语义上的保证。先编写在没有 useMemo 的情况下也可以执行的代码 —— 之后再在你的代码中添加 useMemo,以达到优化性能的目的。

    • useRef

    1、返回一个可变的 ref 对象,useRef 会在每次渲染时返回同一个 ref 对象。

    2、useRef() Hook 不仅可以用于 DOM refs。ref 对象是一个 current 属性可变且可以容纳任意值的通用容器,类似于一个 class 的实例属性。

    • useImperativeHandle

    useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。
    useImperativeHandle 应当与 forwardRef 一起使用:

    在本例中,渲染  的父组件可以调用 inputRef.current.focus()。

    • useLayoutEffect

    其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。
    可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

    无论 useLayoutEffect 还是 useEffect 都无法在 Javascript 代码加载完成之前执行

    若要从服务端渲染的 HTML 中排除依赖布局 effect 的组件,可以通过使用 showChild &&  进行条件渲染,
    并使用 useEffect(() => { setShowChild(true); }, []) 延迟展示组件

    • useDebugValue

    useDebugValue 可用于在 React 开发者工具中显示自定义 hook 的标签。

    延迟格式化 debug 值

    在某些情况下,格式化值的显示可能是一项开销很大的操作。除非需要检查 Hook,否则没有必要这么做。
    因此,useDebugValue 接受一个格式化函数作为可选的第二个参数。该函数只有在 Hook 被检查时才会被调用。它接受 debug 值作为参数,并且会返回一个格式化的显示值。

    自定义HOOK

    自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。
    使用自定义的hook

    自定义 Hook 必须以 “use” 开头

    在两个组件中使用相同的 Hook 会共享 state 吗?

    不会。自定义 Hook 是一种重用状态逻辑的机制,所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。

    自定义 Hook 如何获取独立的 state?

    每次调用 Hook,它都会获取独立的 state。由于我们直接调用了 useFriendStatus,从 React 的角度来看,我们的组件只是调用了 useState 和 useEffect。 我们可以在一个组件中多次调用 useState 和 useEffect,它们是完全独立的。

    Hook异步请求数据

    参考官方文档
    参考链接:https://blog.csdn.net/weixin_44282875/article/details/85336106

  • 相关阅读:
    20201304杨淑钰+快速浏览教材
    20201304 自我介绍
    熟悉编程语言
    俄罗斯方块游戏代码的改写
    2020 -2021-1 20201319 《信息安全专业导论》第八周学习总结
    如何学好编程
    2020-2021-1 20201319 《信息安全专业导论》第七周学习总结
    2020-2021-1 20201319 《信息安全专业导论》第六周学习总结
    实现进制转换伪代码
    斐波那契数列递归实现
  • 原文地址:https://www.cnblogs.com/lyly96720/p/12358168.html
Copyright © 2011-2022 走看看