如何使用useCallback React钩子

Check out my React hooks introduction first, if you’re new to them.

如果您是新手,请先查看我的React hooks简介

One React hook I sometimes use is useCallback.

我有时使用的一个React挂钩是useCallback

import React, { useCallback } from 'react'

This hook is useful when you have a component with a child frequently re-rendering, and you pass a callback to it:

当您的组件具有频繁重新渲染子级的组件,并向其传递回调时,此钩子非常有用:

import React, { useState, useCallback } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0)
  const [otherCounter, setOtherCounter] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }
  const decrement = () => {
    setCount(count - 1)
  }
  const incrementOtherCounter = () => {
    setOtherCounter(otherCounter + 1)
  }

  return (
    <>
      Count: {count}
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={incrementOtherCounter}>incrementOtherCounter</button>
    </>
  )
}

ReactDOM.render(<Counter />, document.getElementById('app'))

The problem here is that any time the counter is updated, all the 3 functions are re-created again.

这里的问题是,每当更新计数器时,都会重新创建所有3个功能。

You can visualize this by instantiating a Set data structure, and adding each function to it. Why Set? because it only stores unique elements, which in our case means different (uniquely instantiated) functions.

您可以通过实例化Set数据结构并将其添加到每个函数来对其进行可视化。 为什么设置? 因为它仅存储唯一元素,在我们的情况下,这意味着不同(唯一实例化)的功能。

import React, { useState, useCallback } from 'react'

const functionsCounter = new Set()

const Counter = () => {
  const [count, setCount] = useState(0)
  const [otherCounter, setOtherCounter] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }
  const decrement = () => {
    setCount(count - 1)
  }
  const incrementOtherCounter = () => {
    setOtherCounter(otherCounter + 1)
  }

  functionsCounter.add(increment)
  functionsCounter.add(decrement)
  functionsCounter.add(incrementOtherCounter)

  alert(functionsCounter)

  return (
    <>
      Count: {count}
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={incrementOtherCounter}>incrementOtherCounter</button>
    </>
  )
}

ReactDOM.render(<Counter />, document.getElementById('app'))

If you try out this code you’ll see the alert incrementing by 3 at a time.

如果您尝试使用此代码,您将看到警报一次增加3。

What should happen instead it’s that if you increment one counter, all functions related to that counter should be re-instantiated.

相反,应该发生的事情是,如果您增加一个计数器,则与该计数器相关的所有功能都应重新实例化。

If another state value is unchanged, it should not be touched.

如果另一个状态值未更改,则不应触摸它。

Now, in most cases this is not a huge problem unless you are passing lots of different functions, all changing unrelated bits of data, that are proven to be a big cost for your app performance.

现在,在大多数情况下,除非您传递许多不同的功能(所有这些不相关的数据都在变化),否则这并不是一个大问题,事实证明,这对提高您的应用程序性能会造成很大的损失。

If that’s a problem, you can use useCallback.

如果有问题,可以使用useCallback

This is how we do it. Instead of:

这是我们的做法。 代替:

const increment = (() => {
  setCount(count + 1)
})
const decrement = (() => {
  setCount(count - 1)
})
const incrementOtherCounter = (() => {
  setOtherCounter(otherCounter + 1)
})

You wrap all those calls in:

将所有这些调用包装在:

const increment = useCallback(() => {
  setCount(count + 1)
}, [count])
const decrement = useCallback(() => {
  setCount(count - 1)
}, [count])
const incrementOtherCounter = useCallback(() => {
  setOtherCounter(otherCounter + 1)
}, [otherCounter])

Make sure you add that array as a second parameter to useCallback() with the state needed.

确保使用所需状态将该数组作为第二个参数添加到useCallback()

Now if you try to click one of the counters, only the functions related to the state that changes are going to be re-instantiated.

现在,如果您尝试单击计数器之一,那么将仅重新实例化与更改状态有关的功能。

You can try this example on Codepen:

您可以在Codepen上尝试以下示例:

See the Pen React useCallback hook by Flavio Copes (@flaviocopes) on CodePen.

见笔阵营useCallback钩由弗拉维奥·科佩斯( @flaviocopes上) CodePen

翻译自: https://flaviocopes.com/react-hook-usecallback/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前言如释重负,好用的技术就应该越来越简单React Hooks 是 React 16.8 从提案转为正式加入的新特性。这个新特性是个非常棒的设计。 可以说对于React 技术栈的发展具分割线一样的意义。讲师在课程中提到:之前使用 React 作为主要的前端技术,开发一款网页游戏。在整个游戏的各个模块中,Redux ,mobx,以及蚂蚁金服的 ant-design,dva, umi 这些框架或者第三方库都有涉及使用。但是自从了解了Facebook官方提案的 Hooks 特性后,才真正觉得获得了前所未有的解脱。如果你有React开发经验,学习了解 Hooks 后,一定有一种如释重负的轻松感。React 带来了方便也带来了迷茫相信关心 React Hooks 这项新特性的童鞋,很多已经有了一定的 React 开发经验。那么你一定有所体验,React 给我们带来方便的同时,也的确和长久以来的前端开发模式有极大的不同。React 并不需要用继承,而是推荐用嵌套。React 有独特的 jsx 语法。大多数情况 jsx 都使得我们的代码更加简洁了。然而有些时候也给我们带来了一些困扰。 比如数据的传递,逻辑的复用。 react 是一种 mvvm 的设计模式,作为开发者一定要清楚,那些数据是业务数据,那些数据是UI数据。否则你的代码很有可能会陷入混乱局面。大型项目中模块化与功能解耦困难在公司项目中 App 稍大的时候,我们发现状态提升和只通过 props 进行数据传递。很多时候都很难实现我们的需求。这时无论我们是否清楚的了解,但是状态管理也就是 redux mobx 等,轻易地进入到了公司的项目中。我们经过初期的尝试发现状态管理,确实比用纯粹的 React 带来了数据传递上的方便,以及代码组织上的清晰。但前提是你看懂且理解了 redux 大神晦涩的官网文档。 本来 React 被设计用来组件化前端开发。但当我们初期使用状态管理,我们常常会过度的使用状态数据,业务逻辑和ui逻辑没有清楚的分离,最终你的应用代码结果可能是:除了少数几个组件是独立的解耦的,大多数组件都因为状态数据的共享而耦合在了一起,且他们也完全依赖状态管理框架。无法再轻松的转移复用。使用高阶组件,属性渲染,渲染回调等高级特性,确实可以帮我们解决模块或功能的解耦问题。但是这些方法,确实有点超出普通“猿类”的技能。且降低了代码的可读性,对于团队协作,这是很致命的问题。React Hooks 真正开启前端模块化的金钥匙对于以上问题,React Hooks 都有很好的解决方案,官方的设计动机就是解决这些曾经的繁琐,化繁为简。React Hooks 让我们在纯函数中就可以使用 React 的众多特性。而不必使用类。代码扁平,易读。解耦状态相关逻辑,UI逻辑和业务逻辑更好的分离。这些逻辑往往是纯函数,而以前很容易混合在类组件中。通过自定义 Hooks 我们可以把应用中“状态相关”逻辑解耦出来,独立编写到我们自己的hooks 中。从而更加易于复用和独立测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值