简体   繁体   English

React Hooks - useCallback 性能

[英]React Hooks - useCallback performance

Im writing my product in React Hooks and yes, Im just new to it.我用 React Hooks 编写我的产品,是的,我刚接触它。

Today I have math about useCallback performance.This makes me consider a lot to use useCallback or not use.今天我有关于 useCallback 性能的数学。这让我考虑了很多使用 useCallback 或不使用。

Let have a look.让我们看看。 As we know, useCallback is use for better performance.众所周知,useCallback 用于提高性能。

function MainScreen() {
  const [email, setEmail] = useState("");
  const [pwd, setPwd] = useState(""):

  const onAuthenticate = useCallback(() => {
    MyApi.authenticate(email, pwd);
  }, [email, pwd]);

  return <div>
    <MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
  </div>;
}

In the example above, let's assume there are two inputs of email and password then MyCustomButton will be rendered all the times email or password changes.在上面的例子中,假设有两个输入的电子邮件和密码,那么MyCustomButton将在电子邮件或密码更改时呈现。 I tried to use useCallback to reduce number times of render but for me, it is not good enough.我尝试使用useCallback来减少渲染次数,但对我来说,这还不够好。

Later, I figured out a way, take out email and pwd in dependencies and use useRef to hold value of email and password.后来想了个办法,把依赖中的email和pwd取出来,用useRef来保存email和password的值。

function MainScreen() {
  const [email, setEmail] = useState("");
  const [pwd, setPwd] = useState(""):

  const emailRef = useRef(email);
  const pwdRef = useRef(pwd);

  const onAuthenticate = useCallback(() => {
    MyApi.authenticate(emailRef.current, pwdRef.current);
  }, []);

  useEffect(() => {
    emailRef.current = email;
    pwdRef.current = pwd;
  }, [email, pwd]);

  return <div>
    <MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
  </div>;
}

With this approach, it stops rendering in MyCustomButton every time email or password changes.使用这种方法,它会在每次电子邮件或密码更改时停止在MyCustomButton呈现。

Is it actually better in performance and cost?它实际上在性能和成本上更好吗? What do you think guys?你们觉得怎么样?

Thanks for sharing.感谢分享。

The issue that I am seeing with your code is not with useCallback - it's with useState .我在您的代码中看到的问题与useCallback ,而是与useState

A rule of thumb in react (whether you use hooks or not) is that the state has a direct impact on what is being displayed. React 的一个经验法则(无论您是否使用钩子)是状态对显示的内容有直接影响。 If you modify the state, it means that the component should be re-rendered.如果修改了状态,则意味着组件应该重新渲染。

This rationale is what makes your component re-render when using useState.这个基本原理是使您的组件在使用 useState 时重新渲染的原因。 React assumes that email and password are things that change how your component should look like, therefore, it is being rerendered whenever you change one of their values. React 假设emailpassword会改变您的组件的外观,因此,只要您更改它们的值之一,它就会重新呈现。

If you don't actually use email and pwd in MyCustomButton , then using useRef instead of useState makes more sense.如果您实际上并未在MyCustomButton使用emailpwd ,那么使用useRef而不是useState更有意义。

However, the way you are using it in your second code sample doesn't make a lot of sense: You are combining useState and useRef so that when email changes (which will be the case when you use setEmail , then you update the ref with the same value. The only benefit that you get out of it is that onAuthenticate is not reconstructed every time.但是,您在第二个代码示例中使用它的方式并没有多大意义:您将useStateuseRef结合useState ,以便当email更改时(使用setEmail时就是这种情况,然后您使用相同的值。您从中获得的唯一好处是不会每次都重新构建 onAuthenticate。

It would be more beneficial to skip useState entirely, but from the code you posted, it is difficult to actually propose a different solution, as it is not clear how/when email and pwd are actually set.完全跳过useState会更有益,但从您发布的代码来看,实际上很难提出不同的解决方案,因为不清楚如何/何时实际设置emailpwd

Since you are only performing an API call, I recommend not to use useCallback() .由于您只是在执行 API 调用,因此我建议不要使用useCallback() Make it a normal function instead.改为使其成为正常功能。

You could be doing a premature optimization.您可能正在进行过早的优化。 You should only do performance optimization, if you are performing heavy computations on your app and you need to memoize your values.如果您在应用程序上执行大量计算并且需要记住您的值,您应该只进行性能优化。

An in-depth comparison of a normal function vs a function that uses useCallback() can be seen from here.这里可以看到普通函数与使用useCallback()的函数的深入比较

in this case, I would like use React.memo instead of useCallback.在这种情况下,我想使用 React.memo 而不是 useCallback。 use React.memo to make sure this component will not call render cased by parent, once component call render, email or pwd have changed, so useCallback is unnecessary使用 React.memo 确保这个组件不会调用父级的渲染,一旦组件调用渲染,电子邮件或密码发生变化,所以 useCallback 是不必要的

function MainScreen() {
  const [email, setEmail] = useState("");
  const [pwd, setPwd] = useState(""):

  const onAuthenticate = () => {
    MyApi.authenticate(email, pwd);
  };

  return <div>
    <MyCustomButton onPress={onAuthenticate}>LOGIN</MyCustomButton>
  </div>;
}
export default React.memo(MainScreen)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM