Javascript 关于useCallback钩子和匿名函数的问题

Javascript 关于useCallback钩子和匿名函数的问题,javascript,reactjs,react-hooks,anonymous-function,usecallback,Javascript,Reactjs,React Hooks,Anonymous Function,Usecallback,在传递回调函数时,尤其是传递参数化函数时,我知道应该使用useCallback钩子,因为使用匿名函数会对性能产生不利影响 我说的匿名函数的例子是这样的 从“React”导入React,{useState}; 常量组件==>{ const[param,setParam]=useState; ... 回来 ... setParam'parameter'} {……其他人} /> ; } 在将匿名函数转换为使用此钩子的过程中,我遇到了一个错误,即“渲染太多”或它无法正常工作。 但我不知道在什么情况下,在

在传递回调函数时,尤其是传递参数化函数时,我知道应该使用useCallback钩子,因为使用匿名函数会对性能产生不利影响

我说的匿名函数的例子是这样的

从“React”导入React,{useState}; 常量组件==>{ const[param,setParam]=useState; ... 回来 ... setParam'parameter'} {……其他人} /> ; } 在将匿名函数转换为使用此钩子的过程中,我遇到了一个错误,即“渲染太多”或它无法正常工作。 但我不知道在什么情况下,在什么情况下

我曾经像下面这样使用过

从“React”导入React,{useState,useCallback}; 常量组件==>{ const[param,setParam]=useState; const handleClick=useCallbackparams=>{ setparams; },[]; ... 回来 ... ; } 但是,当使用匿名函数在useCallback中返回时,它也起作用

这意味着像这里这样的代码。只有与上面代码相比的差异

const handleClick=useCallbackparams=>{ return=>setParams; },[]; 在这种情况下,如果我只是使用匿名函数而不是使用此挂钩,我想知道这是否比在useCallback中使用匿名函数更糟糕。

在您的代码中:

const handleClick=useCallbackparams=>{ setparams; },[]; 您应该将参数传递到useCallback的第二个参数中,如下所示:

const handleClick=useCallbackparams=>{ setparams; },[setParam,param,SETPARAMACTUALVALUE]; //将SETPARAMACTUALVALUE更改为`setParam`钩子的变量名 在代码中:

const handleClick=useCallbackparams=>{ setparams; },[]; 您应该将参数传递到useCallback的第二个参数中,如下所示:

const handleClick=useCallbackparams=>{ setparams; },[setParam,param,SETPARAMACTUALVALUE]; //将SETPARAMACTUALVALUE更改为`setParam`钩子的变量名
如果希望保存函数直到钩子的依赖项发生更改,那么useCallback钩子的用法会更好。它提供了更好的性能,因为钩子可以记住内部函数。

useCallback钩子的用法会更好,如果您想保存函数,直到钩子的依赖关系发生变化。它提供了更好的性能,因为钩子记住了内部函数

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
  );
更好的方法是:

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

const Component = () => {
  const [param, setParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick}
      {...others}
    />
  );
}
回到您的问题,比较性能取决于其他函数定义和组件内部返回函数中子组件的呈现时间。 假设你的应用程序中有另一个名为“anotherHandleClick”的onclickHanldier。 那么您的组件看起来像这样

const Component = () => {
  const [param, setParam] = useState('');
  const [anotherParam, setAnotherParam] = useState('');

  const handleClick = (params) => {
    setParam(params);
  };
const anotherHandleClick =(params) => {
    setAnotherParam(params);
  };
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}
在上面的组件中,当某个组件中的任何一个单击entiere组件时,组件重新呈现,因此处理程序函数是新定义的。当这两个组件都对onclick处理程序函数进行引用相等性检查时,他们认为是新的处理程序函数促使他们呈现这两个组件。 在这种情况下,最好使用useCallBack钩子,如下所示:

const Component = () => {
  const [param, setParam] = useState('');
      const [anotherParam, setAnotherParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);
const anotherHandleClick = useCallback((params) => {
    setAnotherParam(params);
  },[]);
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}
在上面的代码中,当单击任何一个时,状态都会更改。然后在呈现时,使用回调确保onclick处理程序引用没有更改。所以,具有onclick处理程序的依赖关系不会被重新调用

最后一个想法是,在这两种情况下,它都在每个渲染上创建一个函数。第二个,因为它包装在useCallback中,将返回在初始渲染时创建的记忆函数

何时使用useMemo或useCallback

更好的方法是:

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

const Component = () => {
  const [param, setParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);

  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick}
      {...others}
    />
  );
}
回到您的问题,比较性能取决于其他函数定义和组件内部返回函数中子组件的呈现时间。 假设你的应用程序中有另一个名为“anotherHandleClick”的onclickHanldier。 那么您的组件看起来像这样

const Component = () => {
  const [param, setParam] = useState('');
  const [anotherParam, setAnotherParam] = useState('');

  const handleClick = (params) => {
    setParam(params);
  };
const anotherHandleClick =(params) => {
    setAnotherParam(params);
  };
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}
在上面的组件中,当某个组件中的任何一个单击entiere组件时,组件重新呈现,因此处理程序函数是新定义的。当这两个组件都对onclick处理程序函数进行引用相等性检查时,他们认为是新的处理程序函数促使他们呈现这两个组件。 在这种情况下,最好使用useCallBack钩子,如下所示:

const Component = () => {
  const [param, setParam] = useState('');
      const [anotherParam, setAnotherParam] = useState('');

  const handleClick = useCallback((params) => {
    setParam(params);
  },[]);
const anotherHandleClick = useCallback((params) => {
    setAnotherParam(params);
  },[]);
  ...
  return (
    ...
    <SomeComponent
      onClick={handleClick('parameter')}
      {...others}
    />
<SomeComponent
      onClick={antherHandleClick('parameter')}
      {...others}
    />
  );
}
在上面的代码中,当单击任何一个时,状态都会更改。然后在呈现时,使用回调确保onclick处理程序引用没有更改。所以,具有onclick处理程序的依赖关系不会被重新调用

最后一个想法是,在这两种情况下,它都在每个渲染上创建一个函数。第二个,因为它包装在useCallback中,将返回在初始渲染时创建的记忆函数


何时使用useMemo或useCallback

如果您的函数如此之小,我怀疑即使使用useC,您也不会获得任何性能
allback。。但是你失去了很多可读性,而->onClick={params=>setparams}也会这样做。@Keith谢谢你的评论。但这段代码只是一个例子。也许这是一个不恰当的例子。我的问题是,在“useCallback”中返回匿名函数时,仅仅使用匿名函数是否会受到相同的性能损失?换句话说,人们建议使用useCallback,因为匿名函数对性能有负面影响,我想知道当我在“useCallback”中返回一个匿名函数时,如果它们工作正常,我是否可以使用它们。当您需要通过传递函数的相同引用来优化子重渲染,并且子组件是PureComponent/wrapped with React.memo时,请使用useCallback,虽然它记得以前的函数引用,但每次重新渲染时都会创建一个新函数,但会被垃圾回收。好的。谢谢你的评论。这帮了大忙!如果您的函数如此之小,我怀疑即使使用useCallback,您也不会获得任何性能。。但是你失去了很多可读性,而->onClick={params=>setparams}也会这样做。@Keith谢谢你的评论。但这段代码只是一个例子。也许这是一个不恰当的例子。我的问题是,在“useCallback”中返回匿名函数时,仅仅使用匿名函数是否会受到相同的性能损失?换句话说,人们建议使用useCallback,因为匿名函数对性能有负面影响,我想知道当我在“useCallback”中返回一个匿名函数时,如果它们工作正常,我是否可以使用它们。当您需要通过传递函数的相同引用来优化子重渲染,并且子组件是PureComponent/wrapped with React.memo时,请使用useCallback,虽然它记得以前的函数引用,但每次重新渲染时都会创建一个新函数,但会被垃圾回收。好的。谢谢你的评论。这帮了大忙!哦,我匆忙地写了一个错误的代码作为例子。很抱歉但我的问题是,在“useCallback”中返回匿名函数是否会像只使用匿名函数一样降低性能?哦,我匆忙地写了一个错误的代码作为例子。很抱歉但我的问题是,在“useCallback”中返回匿名函数是否会像只使用匿名函数一样降低性能?谢谢你的回答。但是正如你在第三段代码中所说的,我在问这个问题之前写了它,但在本例中,它不起作用,因为没有传递任何参数。也许是因为我写的例子比我遇到麻烦的情况简单得多。所以你的观点是,如果我像我在问题中写的最后一段代码那样写,这对性能不好?当只有一个函数定义时,使用useCallBack是不明智的,因为它比内联处理程序多做了一步。通常反应渲染非常快。但是,当您的组件具有多个函数定义和渲染时间非常长的从属子组件时,最好使用useCallBack。请阅读:为了更好地理解。如果你有更好的视角让我知道,我也能学到。哦,我明白你的意思。谢谢你善意的评论!希望你学到了一些东西。我编辑了答案并添加了粗体描述,这基本上解释了差异。不客气,谢谢你的回答。但是正如你在第三段代码中所说的,我在问这个问题之前写了它,但在本例中,它不起作用,因为没有传递任何参数。也许是因为我写的例子比我遇到麻烦的情况简单得多。所以你的观点是,如果我像我在问题中写的最后一段代码那样写,这对性能不好?当只有一个函数定义时,使用useCallBack是不明智的,因为它比内联处理程序多做了一步。通常反应渲染非常快。但是,当您的组件具有多个函数定义和渲染时间非常长的从属子组件时,最好使用useCallBack。请阅读:为了更好地理解。如果你有更好的视角让我知道,我也能学到。哦,我明白你的意思。谢谢你善意的评论!希望你学到了一些东西。我编辑了答案并添加了粗体描述,这基本上解释了差异。不客气: