<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter Yuan</title>
    <description>The latest articles on DEV Community by Peter Yuan (@peteryuan).</description>
    <link>https://dev.to/peteryuan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F451700%2Faba4ca97-abc3-49f6-9a46-13bb13a31f4e.jpg</url>
      <title>DEV Community: Peter Yuan</title>
      <link>https://dev.to/peteryuan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peteryuan"/>
    <language>en</language>
    <item>
      <title>useCallback VS useMemo</title>
      <dc:creator>Peter Yuan</dc:creator>
      <pubDate>Wed, 14 Aug 2024 07:53:34 +0000</pubDate>
      <link>https://dev.to/peteryuan/usecallback-vs-usememo-5gad</link>
      <guid>https://dev.to/peteryuan/usecallback-vs-usememo-5gad</guid>
      <description>&lt;p&gt;We all know how to use &lt;code&gt;React.useCallback&lt;/code&gt; and &lt;code&gt;React.useMemo&lt;/code&gt;, but sometimes we will be confused about which one we should choose. &lt;/p&gt;

&lt;p&gt;Here I will show you guys some cases to help you understand what hook function we should use in some specific situations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)

  return &amp;lt;div&amp;gt;{num1 + num2}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above simple example case, we can just get the sum by &lt;code&gt;num1 + num2&lt;/code&gt; in the HTML element part, but if we have some more complex calculation logic, we shouldn't do that anymore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useMemo } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)

  const sum = useMemo(() =&amp;gt; {
    const _num1 = Number(num1),
      _num2 = Number(num2)
    if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
      return "check your num's type"
    }
    return _num1 + _num2
  }, [num1, num2])

  return &amp;lt;div&amp;gt;{sum}&amp;lt;/div&amp;gt;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example code block, we chose &lt;code&gt;useMemo&lt;/code&gt; to keep the result value of &lt;code&gt;num1 + num2&lt;/code&gt;, but we add some type check logic, because we can't totally trust the num1 or num2's type would be number, so when the type goes wrong, we will show the placeholder text. &lt;/p&gt;

&lt;p&gt;In this situation, you can't realize this effect in the HTML part with simple code in one line. Of course, you can write some logic code in the HTML part with conditional operators (JSX allow you to do that), but the cost is sacrificing the readability of the code.&lt;/p&gt;

&lt;p&gt;So, &lt;code&gt;useMemo&lt;/code&gt; is a good choice to handle this case. &lt;/p&gt;

&lt;p&gt;Ok, let's go on one more complex case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useMemo } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sum1 = useMemo(() =&amp;gt; {
    const _num1 = Number(num1),
      _num2 = Number(num2)
    if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
      return "check your num's type"
    }
    return _num1 + _num2
  }, [num1, num2])

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div&amp;gt;{sum1}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{num3 + num4}&amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have num3 and num4 here to render the sum of them. If we also want to reuse the logic of &lt;code&gt;num1 + num2&lt;/code&gt;, what should we do? Of course we can still use &lt;code&gt;useMemo&lt;/code&gt; to define one sum2, but it's not a good idea to reuse the logic to validate the num's type. So we need split the validate logic out from the &lt;code&gt;useMemo&lt;/code&gt;. Then &lt;code&gt;useCallback&lt;/code&gt; shows up!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useCallback } from 'react'

const validteNumAndSum = (number1, number2) =&amp;gt; {
  const _num1 = Number(number1),
    _num2 = Number(number2)
  if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
    return "check your num's type"
  }
  return _num1 + _num2
}

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sumFunc = useCallback(validteNumAndSum, [])

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div&amp;gt;{sumFunc(num1, num2)}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{sumFunc(num3, num4)}&amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we use &lt;code&gt;useCallback&lt;/code&gt; to return a new function with the logic of validating num's type and calculating the sum, and we reuse this &lt;code&gt;validteNumAndSum&lt;/code&gt; function in the HTML part easily. &lt;/p&gt;

&lt;p&gt;Ok, let's go to the conclusion part:&lt;/p&gt;

&lt;p&gt;If you can easily make a calculation (math or more complex situation), you don't need both of them &lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If your calculation logic is complex and just needs to be calculated once only, you can pick the &lt;code&gt;useMemo&lt;/code&gt; hook to package your calculation process and return one simple result. &lt;/p&gt;

&lt;p&gt;But if you would use the same logic more than one time, you can choose &lt;code&gt;useCallback&lt;/code&gt; to return a memorized function to reuse it in your component. &lt;/p&gt;




&lt;p&gt;I am so sorry about &lt;code&gt;useCallback&lt;/code&gt; case. I made a mistake that is to explain when to choose &lt;code&gt;useCallback&lt;/code&gt; and created a bad example case. &lt;/p&gt;

&lt;p&gt;Here I will try again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useCallback } from 'react'

export default function App() {
  const [base, setBase] = useState(0)
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sumFunc = useCallback(
    (number1, number2) =&amp;gt; {
      const _num1 = Number(number1),
        _num2 = Number(number2)
      if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
        return "check your num's type"
      }
      return _num1 + _num2 + base
    },
    [base],
  )

  return (
    &amp;lt;&amp;gt;
      &amp;lt;input
        type="number"
        value={base}
        onChange={e =&amp;gt; {
          setBase(Number(e.target.value))
        }}
      /&amp;gt;
      &amp;lt;div&amp;gt;{sumFunc(num1, num2)}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{sumFunc(num3, num4)}&amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we add one &lt;code&gt;base&lt;/code&gt; number as another variable data, and every sum should be added with the &lt;code&gt;base&lt;/code&gt; value, and we have an &lt;code&gt;input&lt;/code&gt; to change the value of &lt;code&gt;base&lt;/code&gt;, so every time &lt;code&gt;base&lt;/code&gt; is changed and &lt;code&gt;sumFunc&lt;/code&gt; would be modified too, and we can use it to calculate the right result. &lt;/p&gt;

&lt;p&gt;So I will update my conclusion about &lt;code&gt;useCallback&lt;/code&gt;: if we just need to reuse some logic, we can package this logic into a function and even split it out from the component as a util function to reuse it anywhere. And if our logic still relies on some variable of the component, we can use &lt;code&gt;useCallback&lt;/code&gt; to package the logic and return a memorized new function. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop abuse React Context API</title>
      <dc:creator>Peter Yuan</dc:creator>
      <pubDate>Wed, 14 Aug 2024 03:18:12 +0000</pubDate>
      <link>https://dev.to/peteryuan/stop-abuse-react-context-api-5dp</link>
      <guid>https://dev.to/peteryuan/stop-abuse-react-context-api-5dp</guid>
      <description>&lt;p&gt;Several days ago I was adjusted to a new department. My new coworker gave me a task to refactor an existing React project.&lt;/p&gt;

&lt;p&gt;When I was reading the code, I was shocked by the way of using the Context API. The coder before, who put everything (yes, almost everything) into a Context object, treated it as a store to manage all the states and even some local temp state. That's insane! &lt;/p&gt;

&lt;p&gt;And he also codes everything for a page in just one (yes, absolutely only one) component in one .ts file. It's so hard for me to make it clear in my mind about the code's logic. But I still accept these shitty code (I have no choice), so I make a big decision: I would rewrite all these pages in one week with Mobx and split the code into different functional components. &lt;/p&gt;

&lt;p&gt;With Mobx, I create several stores to handle all data from the APIs and split one huge component into different small pieces; everything starts to become clear and simple. Local state should be in its scope where it would be used, the common part will be got from the store of Mobx.&lt;/p&gt;

&lt;p&gt;Finally I totally removed the Context object, thousands of lines of code were removed, and the world is quiet again! &lt;/p&gt;

&lt;p&gt;I want to say something about Context API. If you really have something, such as some global config information to share to the entire app, you can use Context API, But if you just want to avoid using some third-party state management library, that's a bad idea to treat context as a replacement. &lt;/p&gt;

&lt;p&gt;Let Context be Context and let state be managed by libraries like Mobx. &lt;/p&gt;

&lt;p&gt;Stop abuse React Context API, please!&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>What is Perfect Code in your heart?</title>
      <dc:creator>Peter Yuan</dc:creator>
      <pubDate>Thu, 13 Aug 2020 03:08:37 +0000</pubDate>
      <link>https://dev.to/peteryuan/what-is-perfect-code-in-your-heart-55c1</link>
      <guid>https://dev.to/peteryuan/what-is-perfect-code-in-your-heart-55c1</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fieexr88jr2qo0dv38p7u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fieexr88jr2qo0dv38p7u.jpeg" alt="Alt Text" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What kind of code is perfect?&lt;/p&gt;

&lt;p&gt;How to define perfect?&lt;/p&gt;

&lt;p&gt;What's your standard?&lt;/p&gt;

&lt;p&gt;How do you request yourself?&lt;/p&gt;

&lt;p&gt;Do you have some principles to share?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
