当前位置: 首页 > 知识库问答 >
问题:

React Hooks:有什么原因可以解释为什么省略创建或分别为use效应和useCallback的回调是不好的吗?

姚宪
2023-03-14

所以我在读丹·阿布拉莫夫和霍克斯博士的《使用效果完整指南》。

在文章中,Dan给出了以下示例:

function SearchResults() {
  const [query, setQuery] = useState('react');

  // ✅ Preserves identity until query changes
  const getFetchUrl = useCallback(() => {
    return 'https://hn.algolia.com/api/v1/search?query=' + query;
  }, [query]);  // ✅ Callback deps are OK

  useEffect(() => {
    const url = getFetchUrl();
    // ... Fetch data and do something ...
  }, [getFetchUrl]); // ✅ Effect deps are OK

  // ...
}

钩子文档给出了:

function ProductPage({ productId }) {
  // ✅ Wrap with useCallback to avoid change on every render
  const fetchProduct = useCallback(() => {
    // ... Does something with productId ...
  }, [productId]); // ✅ All useCallback dependencies are specified

  return <ProductDetails fetchProduct={fetchProduct} />;
}

function ProductDetails({ fetchProduct })
  useEffect(() => {
    fetchProduct();
  }, [fetchProduct]); // ✅ All useEffect dependencies are specified
  // ...
}

我想知道:回调和工厂函数真的有必要吗?

你也可以写:

const getFetchUrl = useCallback('https://hn.algolia.com/api/v1/search?query=' + query, [query]);

useEffect(fetchProduct, [fetchProduct]);

类似地,你可以想象一个场景,你可以把创建函数留给useMemo

function Greeting({ name }) {
  const calculateExpensive = useCallback(() => {
    return `Hello ${name}`;
  }, [name]);

  const result = useMemo(calculateExpensive, [calculateExpensive]);
  return <p>{result}</p>;
}

我肯定我在这里犯了一个愚蠢的错误。我没有看到什么,做错了什么?

共有1个答案

司寇昱
2023-03-14

使用useCallback的原因是为了在需要时在呈现之间保持对函数的相同引用。

顾名思义,useCallback应该接受回调函数作为参数。因为useCallback(fn)usemo(()=

const getFetchUrl = useCallback('https://hn.algolia.com/api/v1/search?query=' + query, [query]);

这样做没有任何好处,因为usemouseCallback用于惰性评估,而这会导致急切的评估。

getFetchUrl回调的例子不是很说明问题,因为备忘录化没有提供任何改进,它可以简化为:

function SearchResults() {
  const [query, setQuery] = useState('react');

  const fetchUrl = 'https://hn.algolia.com/api/v1/search?query=' + query;

  useEffect(() => {
    // ... Fetch data and do something ...
  }, [fetchUrl]);
}

对于问候示例,useCallback是多余的。如果计算非常昂贵,需要懒惰地评估(在本例中不是),这就是useMemo的作用:

function Greeting({ name }) {
  const result = useMemo(() => {
    return `Hello ${name}`;
  }, [name]);

  return <p>{result}</p>;
}

 类似资料:
  • 问题内容: 为什么每个人都告诉我编写这样的代码是一种不好的做法? 我省略花括号的最大论据是,有时花括号可能是花括号的两倍。例如,以下代码为C#中的标签绘制发光效果。 您还可以获得链接usings在一起的额外好处,而不必缩进一百万次。 花括号的最常见参数涉及维护编程,以及在原始if语句及其预期结果之间插入代码会引起的问题: 问题: 想要使用该语言提供的更紧凑的语法是错误的吗?设计这些语言的人很聪明,

  • 问题内容: 什么是决定不具有的接口完全通用的get方法背后的原因。 为了澄清这个问题,方法的签名是 代替 我想知道为什么(与相同)。 问题答案: 正如其他人所提到的,之类的原因不是通用的,因为你要检索的条目的键不必与你传递给的对象的类型相同;方法的规范仅要求它们相等。这从方法如何将对象作为参数(而不仅仅是与对象相同的类型)中得出。 尽管通常已经定义了许多类,以便其对象只能等于其自己的类的对象,这确

  • 当然在文件结束或输入错误发生时返回,但这是否意味着没有更多的数据可用? 使用

  • 问题内容: 是具有所有已实现方法的抽象类。为什么是抽象的? 我得到的最常见答案是,限制的实例化。但是还有其他方法可以执行此操作,例如私有构造函数将限制实例化。 我了解他们遵循模板方法设计模式。如果某些方法是抽象的,那么即使他的业务逻辑不需要它们,用户也将最终实现所有这些方法。 但是,如果不是抽象的,用户仍然可以扩展它并覆盖require方法。 至少从“抽象”一词的字典含义来看,使用所有已实现方法的

  • 问题内容: 我了解JSON,但不了解JSONP。Wikipedia上有关JSON的文档是JSONP的最高搜索结果。它说: JSONP或“带填充的JSON”是JSON扩展,其中将前缀指定为调用本身的输入参数。 ??什么电话 这对我来说毫无意义。JSON是一种数据格式。没有电话 在第二个搜索结果是由某些人叫雷米,谁写的这个约JSONP: JSONP是脚本标记注入,它将响应从服务器传递到用户指定的函数。

  • 本文向大家介绍解释下 CSS sprites的原理和优缺点分别是什么?相关面试题,主要包含被问及解释下 CSS sprites的原理和优缺点分别是什么?时的应答技巧和注意事项,需要的朋友参考一下 我来说下我的观点 原理: 多张图合并成一张图 优点&解决的问题 hover效果,如果是多个图片,网络正常的情况下首次会闪烁一下。如果是断网情况下,就没图片了。sprites 就很好的解决了这个问题(第一次