๐ useEffect VS useLayoutEffect ๐
๐ธ TIL
ํ์ฌ์์ ๋ด๋นํ๊ณ ์๋ React-Native ์ฑ์ ๊ตฌํํ๋ ์ค์ Navigation ์ค์ Stack.Screen์ ์ฌ์ฉํ์ฌ Header Bar๋ฅผ ์ปค์คํ ํ์ฌ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ฒผ๋ค.
๋จผ์ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ์๋จ์ header๊ฐ ์๊ณ navigation.push()๋ฅผ ํตํด ํ์ด์ง๋ฅผ ์ด๋ํ์ ์ header ์ผ์ชฝ์ ์ด์ ๋ฒํผ์ด ๋ณด์ฌ์ง๊ฒ ๋๋๋ฐ, ๋ด๊ฐ ๊ตฌํํด์ผ ํ๋ ๊ฒ์ ์ด์ ๋ฒํผ์ ์ฌ์ฉํ์ง ์๊ณ header์ ๋ด๊ฐ ์ง์ ํ๊ณ ์ถ์ ์ด๋ฏธ์ง๋ ๋ฒํผ ๋ฑ๋ฑ์ ์ปค์คํ ํ์ฌ ๋ง๋ค์ด๋ด๋ ๊ฒ์ด์๋ค.
import React, { useState } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
const App = ({ navigation }: any) => {
const [disabled, setDesabled] = useState(true);
navigation.setOptions({
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text>์ทจ์</Text>
</TouchableOpacity>
),
headerRight: () => (
<TouchableOpacity
disabled={disabled}
onPress={() => alert('hi')}
>
<Text style={disabled ? {color: '#cdccd'} : {color: '#111'}} >ํ์ธ</Text>
</TouchableOpacity>
),
});
return (
<View>
<Text>Hello World</Text>
</View>
);
};
export default App;
์์ ๊ฐ์ด navigation.setOptions()๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ์ปดํฌ๋ํธ์ Header๋ฅผ ์ปค์คํ ํ ์ ์๊ฒ ๋์๋๋ฐ ์ด๋ ๊ฒ ์์ฑํ์ ํฐ๋ฏธ๋์ ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๋ฅผ ๋ง์ฃผํ๊ฒ ๋์๋ค.
๐ซ Warning: Cannot update a component from inside the function body of a different component.
์ด ์๋ฌ๊ฐ ์ ์๊พธ ๋์ค๋์ง ๊ตฌ๊ธ๋ง์ ํ ๊ฒฐ๊ณผ ์ด์ด์๊ฒ๋ useEffect ๋ฅผ ์ฌ์ฉํด์ฃผ๋ ๊ฒ์ ๊น๋นกํ๋ค...
๊ทธ๋์ useEffect๋ก ํด๋น ์ฝ๋๋ฅผ ๊ฐ์ธ์ฃผ์๋ค.
import React, { useState } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
const App = ({ navigation }: any) => {
const [disabled, setDesabled] = useState(true);
useEffect(() => {
navigation.setOptions({
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text>์ทจ์</Text>
</TouchableOpacity>
),
headerRight: () => (
<TouchableOpacity
disabled={disabled}
onPress={() => alert('hi')}
>
<Text style={disabled ? {color: '#cdccd'} : {color: '#111'}} >ํ์ธ</Text>
</TouchableOpacity>
),
});
},[disabled]);
return (
<View>
<Text>Hello World</Text>
</View>
);
};
export default App;
useEffect๋ฅผ ํตํด ์๋ฌ๋ ํด๊ฒฐ์ด ๋์์ง๋ง ํด๋น ์๋ฌ์ ๋ํด ์ข ๋ ์์๋ณด๊ณ ์ถ์ด์ ์๋ฌ๋ฅผ ๋ณต์ฌํ์ฌ ๊ตฌ๊ธ๋งํ ๊ฒฐ๊ณผ ๊ณต์๋ฌธ์์์ ์ด navigation.setOptions()๋ฅผ useLayoutEffect()๋ผ๋ Hook์ผ๋ก ๊ฐ์ธ์ ์ฌ์ฉํ๊ณ ์์๋ค.
useLayoutEffect๋ ์ฒ์ ์ ํด๋ณด๋ Hook์ด๋ผ์ useEffect์ ์ด๋ค ์ฐจ์ด์ ์ด ์๋์ง ๊ตฌ๊ธ๋ง์ด ์ข ๋ ํ์ํ๋ค.
๐ ์ฐธ๊ณ ๋ ํผ๋ฐ์ค
๐ฅ useLayoutEffect์ useEffect์ ์ฐจ์ด์
useEffect | useLayoutEffect | |
render | ๋ ๋๊ฐ ํ๋ฉด์ ๊ทธ๋ ค์ง ํ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ | ๋ ๋๋ง ํ ํ๋ฉด์ด ์ ๋ฐ์ดํธ ๋๊ธฐ ์ ์ ๋๊ธฐ์ ์ผ๋ก ์คํ |
์ฌ์ฉ ๊ฒฝ์ฐ | โ๏ธ ์ผ๋ถ ์ํ๋ฅผ ์ฆ์ ๋ฐ์ํ ํ์๊ฐ ์์ ๊ฒฝ์ฐ โ๏ธ ํ์ด์ง์ ์๊ฐ์ ์ผ๋ก ์ํฅ์ ์ฃผ์ง ์๋ ๋ฌด์ธ๊ฐ๋ฅผ ๋๊ธฐํ ํ ๊ฒฝ์ฐ โ๏ธ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค์ ํ๋ ๊ฒฝ์ฐ โ๏ธ ๋ชจ๋ฌ ์์๊ฐ ๋ํ๋๊ฑฐ๋ ์ฌ๋ผ์ง ๋ ์ผ๋ถ ์ํ๋ฅผ ์ฌ์ค์ ํ๋ ๊ฒฝ์ฐ |
โ๏ธ ์ํ๊ฐ ์
๋ฐ์ดํธ ๋ ๋ ์์๊ฐ ๊น๋ฐ์ด๋ ๊ฒฝ์ฐ โ๏ธ DOM์ ๋ณ๊ฒฝํ๋ ค๋ ๊ฒฝ์ฐ |
์ด ๋์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ ๋ ๋๋ง ์์ ์ ์๋ค. |
์์ ์ฐจ์ด์ ๋ง ๋ณด๋ฉด DOM์ ๋ณ๊ฒฝํ๋ ค๋ ๊ฒฝ์ฐ๊ฐ ์ค๊ฑฐ๋ ํ๋ก ํธ๋ฅผ ๊ตฌํํ๊ณ ์๋ค๋ฉด ํ๋ฒ์ฏค ๋ง์ฃผํ๋ ์ํ๋ณ๊ฒฝ์ผ๋ก ์ธํ ์์์ ๊น๋ฐ๊ฑฐ๋ฆผ์ ๋ถ์์ฐ์ค๋ฌ์ด UI๋ฅผ ๋ง์ฃผํ๊ฒ ๋๋ฉด์ " ์ ๊ทธ๋ฌ๋ฉด ์ด๋ฐ ๊ฒฝ์ฐ์๋ ๋ฌด์กฐ๊ฑด useLayoutEffect๊ฐ ์ข๊ฒ ๋ค? " ๋ผ๋ ์๊ฐ์ ํ๊ฒ ๋ ์ ์๋ค.
( ์ด.......................๋ด๊ฐ ๊ทธ๋ฌ๋ค............................)
๊ทธ๋์ ์ ๋ง ๋ด ํ๋จ์ด ๋ง๋๊ฑด์ง ๊ถ๊ธํ์ฌ ๊ตฌ๊ธ๋ง์ ํ ๊ฒฐ๊ณผ ์ด๋ค ๊ฒฝ์ฐ์๋ useEffect ๋์ useLayoutEffect๊ฐ ๋ ์ข๋ค๋ ๊ธ๋ ๋ณด์๋ค.
๋ง์น๋ฉฐ ๐ธ
์.... ๋ด ํ๋จ์ " ๋๋ถ๋ถ์ ๊ฒฝ์ฐ์๋ useEffect๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ๊ณ ์๊ฐ์ ์ธ ๊น๋นก์ ๊ฐ์ ๊ฒฝ์ฐ์๋ง ์ ์ ํ๊ฒ ํ๋จํ์ฌ useLayoutEffect๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๊ฒ ๋ค " ๋ผ๋ ํ๋จ์ ๋ด๋ ธ๋ค.
์ฌ์ค Hook์ ์ผ๋ง๋ ๋ง์ด ์ฌ์ฉํ๋๋๊ฐ ์ค์ํ๋ค๊ธฐ ๋ณด๋ค๋ ์ด๋ ๊ฒฝ์ฐ์ ์ด๋ค Hook์ ์ ์ ํ๊ฒ ์ฌ์ฉํ๋๋๊ฐ ๋ ์ค์ํ ๊ฒ ๊ฐ๋ค.
๊ทธ์ " ์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ด ์ฝ๋๋ฅผ ์ ์ฉํ๋๋ผ " ๊ฐ ์๋๋ผ " ์ด ๊ฒฝ์ฐ์๋ ์ ์ด๋ฐ ์ฝ๋๋ฅผ ์ ์ฉํด์ผํ์ง? " ๋ฅผ ๋จผ์ ์๊ฐํ๊ณ ๊ทธ์ ๋ฐ๋ฅธ ๋ต์ ์์ ์๊ฒ ํ ์ ์๋ค๋ฉด ๊ทธ ๋๊ตฌ๋ ๋นํํ ์ ์๋ ์ข์์ฝ๋๋ผ๊ณ ์๊ฐํ๋ค.