후크에 대해 이야기해 봅시다 - 2부(useLayoutEffect 및 useMemo)
React Hook 시리즈를 계속하면서, 이제
useLayoutEffect
와 useMemo
이라는 또 다른 2개의 Hook에 대해 이야기할 것입니다. 주제로 이동합니다!하지만 그 전에 이 두 가지는 특정 사용 사례가 있을 때만 사용할 수 있는 희귀한 고리라는 점을 언급하고 싶습니다(아직 만나지 않았지만). 하지만 걱정하지 마세요. 기존 프로젝트에서 이 후크를 발견하고 이 두 후크가 어떻게 작동하는지 이해하고 싶을 수도 있습니다. 글쎄, 나는 당신을 덮었습니다!
시작할까요?
이 문서에서 다루는 주제는 다음과 같습니다.
useLayoutEffect
- Yet another lifecycle hook! useEffect
and useLayoutEffect
, and why it matters useMemo
- The memoization hook useMemo
useLayoutEffect - 또 다른 라이프사이클 후크!
In the previous article in this series, I explained how useEffect
is one of the most used hook works. To simply put it a way to understand, it covers componentDidMount
and componentWillUnmount
. Well, useLayoutEffect
does a lot of the same thing as useEffect
, and in fact, the way you write useLayoutEffect
is the same!
useLayoutEffect(() => {
// do your `componentDidMount` thing here
return () => {
// do your `componentWillUnmount` here
};
}, [<all_dependencies_here>]);
useEffect(() => {
// do your `componentDidMount` here
return () => {
// your `componentWillUnmount` here
};
}, [<all_dependencies_here>]);
Welp, two hooks with quite similar names, with the same way to write them. What is the catch?
useEffect와 useLayoutEffect의 차이점과 중요한 이유
However, what difference does it make compared to useEffect
then?
Well, need to know a key difference of "when" both of these hooks run. useEffect
will run right after if there are any changes to any of the given dependencies to the hook, while useLayoutEffect
will run after each change to the "layout", which means if there is a change to the DOM (DOM mutations). This includes if the change involves ref as well.
Not to be mistaken, you indeed supply the same array of dependencies to useLayoutEffect
as you supplied to useEffect
, but it will run after the DOM change, and if any of the dependency changes. Unlike useEffect
which will run right after one of the dependencies changes.
So, when to use useEffect
and when to use useLayoutEffect
? Well, since useEffect
is triggered as the dependencies change, useEffect
is the hook you will use most of the time. useEffect
is DOM independent, which means that DOM doesn't affect the behaviour of useEffect
. Simply, useEffect
is to monitor state changes.
useLayoutEffect
triggers when there is a DOM mutation, so you can utilise that if you need to do some DOM-related activities, such as measuring performance, or detect DOM changes such as scroll position.
useMemo - 메모이제이션 후크
The fourth hook in this series is useMemo
. This is for memoization. So what is memoization?
In programming, memoization is an optimization technique that makes applications more efficient and hence faster. It does this by storing computation results in a cache and retrieving that same information from the cache the next time it's needed instead of computing it again. - Germán Cocca, freeCodeCamp
Memoization is an optimization technique, so your app becomes faster by utilising caches. Just imagine, you are calculating the value of infinity, so you don't want to run it every time the component rerenders, right?
const [x, setX] = useState(0);
const valueOfInfinity = () => calculationOfInfinity(x);
Just imagine, this function will run EVERY TIME component rerenders 🥶
But first, let's see how useMemo is written, shall we?
useMemo(() => {}, [array_of_deps]);
// example
const valueOfInfinity = useMemo(() => calculationOfInfinity(x), [x]);
The first part of the useMemo
hook is the function you want to run. It could be an expensive function or something you want to keep a cache of the dependency. The expensive function here means that this requires a lot of resources to run the function.
The second part of the hook is the array of dependencies. And yes, it behaves similar to useEffect
, where it will only run the function when one of the dependency change value.
Let's say we consider the example above. Just imagine the formula to calculate infinity is extremely complex, and it will surely consume a lot of resources each time the function runs, right? And adding to that, it depends on x
, which possibly changes, since it is a state.
When you trigger useState
, it will trigger the rerenders. When that happens, the function will run each time, even though the state value is unchanged. You could even trigger the useState
to value "3" even though the value is already "3". But since setState
is triggered, the component will rerender anyway.
We don't want that to happen. If the value of dependency is unchanged, we want to keep it that way and not trigger the function. So useMemo
will hold the value of dependency and will observe the changes, so if the value is the same as the previous value, it won't run the function. So, even though we set x
to 3, even though x
is already equal to 3, the function won't run. Neat, right?
This can also be used to avoid children's rerenders too. Example:
const TheButton = useMemo(() => <button>This button</button>, []);
// In your return
return () => (
<TheButton />
);
In this example above, since you didn't add any dependency to the <button>
component, it will only run once. Even though your parent component rerenders, <TheButton>
won't rerender, since it will be the same throughout the component lifecycle. But of course, a simple component like the above example is too simple, and note that the component should be a pure component.
useMemo를 사용하지 않는 경우
Well, you just feel like "Hey, that means I can optimise everything by sprinkling useMemo
everywhere in my code, right?
Chotto matte! If you have this thought, you need to rethink your decision. Most of the time, useMemo
make your app less optimised than you think!
const [x, setX] = useState(0);
const [y, setY] = useState(1);
const theSum = useMemo(() => x + y, [x, y]);
Even if you can calculate x plus y using your fingers, why do you think your app needs to monitor changes for x and y, for the sake of adding x to y?
Most of the time, huge calculations are done by the backend, and the frontend will only retrieve the value from the API, and display it to the user.
So, to what level of complexity do you need to use useMemo
? The answer is, it is so rare unless you need to calculate the value of infinity during rerenders. Personally, I didn't use useMemo
, except for once, which is to calculate the effective interest rate of a loan based on several variables. Since that is a frontend-only app, so I had to use it. If you ask me, I do feel that the calculation might not need useMemo
in the first place.
결론
That's it about useLayoutEffect
and useMemo
. Though they are hooks provided by React, the use case for them is not as easy as you think, thus the usage of these hooks is quite rare. At least, you know how to write them and how they work, so when you need to use these hooks by encountering the use case, you already know how to use them.
While useMemo
is keeping the cache of its dependency for it to run the function, then what is useCallback
? Well, keep yourself posted for the next article on the React hooks!
And as usual, take care of yourselves, and peace be upon ya!
Reference
이 문제에 관하여(후크에 대해 이야기해 봅시다 - 2부(useLayoutEffect 및 useMemo)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alserembani/lets-talk-about-hooks-part-2-uselayouteffect-and-usememo-3f5h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)