๋ชฉ์ฐจ
์ด์ ๊ธ โผ
0. 2023.05.05 - [๐ | WEB DEV/React] - [React] 0. React๋ฅผ ์ฌ์ฉํ๋ ์ด์ & ์ด๊ธฐ ์ธํ
1. 2023.05.07 - [๐ | WEB DEV/React] - [React] 1. JSX
2. 2023.05.26 - [๐ | WEB DEV/React] - [React] 2. state (๋ณ์, array, object)
2-1. 2023.05.27 - [๐ | WEB DEV/React] - [React] 2-1. array state ์ ๋ ฌํ๊ธฐ ( .sort()ํ์ฉ)
3. 2023.05.28 - [๐ | WEB DEV/React] - [React] 3. ์ปดํฌ๋ํธ (Component)
4. 2023.05.28 - [๐ | WEB DEV/React] - [React] 4. ๋์ ์ธ UI ์ ์ํ๊ธฐ
5. 2023.05.28 - [๐ | WEB DEV/React] - [React] 5. ๋ฐ๋ณต๋๋ ๋ถ๋ถ ์ถ์ฝํ๊ธฐ (map)
6. 2023.05.29 - [๐ | WEB DEV/React] - [React] 6. props
8. 2023.07.06 - [๐ | WEB DEV/React] - [React] 8. ๋ค๋ฅธ ํ์ผ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
11. 2023.10.03 - [๐ | WEB DEV/React] - [React] 11. ๋ผ์ฐํ -3 ์์ฐํ ๋ผ์ฐํ
13. 2024.01.02 - [๐ | WEB DEV/React] - [React] 13. ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ Lifecycle์ useEffect
์ปดํฌ๋ํธ๋ฅผ ์ ํํ ๋ ํจ๊ณผ๋ฅผ ๋ฃ์ด๋ณด์!
์ด์ ํฌ์คํธ์ ์ด์ด์ง๋๋ค!
1. ์ ํํจ๊ณผ๋ฅผ ์ํ 4step
์ปดํฌ๋ํธ ์ ํ ๊ณผ์ ์ ์๋์ 4๋จ๊ณ๋ฅผ ๊ฑฐ์ณ์ ๋ง๋ค์ด์ฃผ๋ฉด ๋๋ค.
[์ ํํจ๊ณผ 4step]
1) ๋์ ์ style ๋ด์ className ์์ฑ
2) ๋์ ํ style ๋ด์ className ์์ฑ
3) transition ์์ฑ ์ถ๊ฐ
4) ์ํฉ์ ๋ฐ๋ฅธ 2)๋ฒ className ์ ๊ฑฐor์์ฑ
2. ์ ์ ๋ฐฉ๋ฒ
์๋์ ๊ฐ์ด ๋ฉ๋ด ํญ์ ํด๋ฆญํ๋ฉด ์๋์ ์ปจํ ์ธ ์ปดํฌ๋ํธ๊ฐ ๋ฐ๋๊ณ , ์ด๋ค์๊ฒ ์ ํํจ๊ณผ๋ฅผ ๋ฃ์ด๋ณด์.
1) ๋์ ์ style ๋ด์ className ์์ฑ
.unselected{
transform: scale(0);
}
2) ๋์ ํ style ๋ด์ className ์์ฑ
.selected{
transform: scale(100%);
}
3) transition ์์ฑ ์ถ๊ฐ
0.3์ด์ ์ ํ์๊ฐ์ ๋ถ์ฌํ์๋ค.
.selected{
transform: scale(100%);
transition: .3s
}
4) ์ํฉ์ ๋ฐ๋ฅธ 2)๋ฒ className ์ ๊ฑฐor์์ฑ
- className ๋ฌ์์ฃผ๊ธฐ
์ ํ ์ , ํ๋ฅผ ๋์ ํ๊ทธ์ ๋ฌ์์ค ํ,
์ ํ ํ style์ ๋ด์ className์ ์ ํ ์ด๋ฒคํธ ๋ฐ์ ์ ์ ๊ฑฐ->์์ฑํด์ค ๊ฒ์ด๋ค.
(์ ํ ์ : unselected, ์ ํ ํ: selected)
...
<div className="tab-content">
{
<RenderTab idx={tabIdx}/>
}
</div>
...
์์ ๊ฒฝ์ฐ์๋ ์ปดํฌ๋ํธ๋ฅผ ์ ์ํ์๊ธฐ ๋๋ฌธ์ <RenderTab/>์ className์ ์ง์ ๋ค๋ ๊ฒ์ด ์๋
์๋์ฒ๋ผ ์ค์ ๋ก ๋ ๋๋ง ๋๋ ํ๊ทธ์ ๋ฌ์์ฃผ์ด์ผ ํ๋ค.
function RenderTab({idx}){
return(
<div className={"unselected selected"}>
{
[ <Tab1/>, <Tab2/>, <Tab3/> ][idx]
}
</div>
)
}
- className ์ ์ด
ํ์์๋ selected๋ผ๋ className์ด ๋ถ์ด์์ง ์์ง๋ง
state๋ฅผ ์ด์ฉํด์ tab์ด ๋ฐ๋๋ ๊ฒฝ์ฐ ๋ถ๋๋ก ํด๋ณด์.
className์ ์ ์ดํ ๋ ์ฃผ์ํ ์ ์ "unselected "์ฒ๋ผ ๊ณต๋ฐฑ์ ๋์ด์ผํ๋ค๋ ์ ์ด๋ค.
๋์ง ์๋๋ค๋ฉด "unselectedselected" ๋ผ๋ ํ๋์ className์ผ๋ก ์ธ์๋๊ธฐ ๋๋ฌธ์
์ํ๋ style์ ์ ์ฉํ ์ ์๋ค!
function RenderTab({idx}){
const [pop, setPop] = useState("");
useEffect(()=>{
setTimeout(() => {
setPop("selected");
}, 100);
return()=>{
setPop("")
}
},[idx])
return(
<div className={"unselected " + pop}>
{
[ <Tab1/>, <Tab2/>, <Tab3/> ][idx]
}
</div>
)
}
โ ์ด๊ธฐํ
pop ์ด๋ผ๋ state๋ฅผ ์์ฑํด์ค ๋ค, "" ์ผ๋ก ์ด๊ธฐํํ์๋ค.
const [pop, setPop] = useState("");
โก ํด๋ฆญ ์ (์ปดํฌ๋ํธ ์์ฑ)
setPop("") : "unselected " / setPop("selected") : "unselected selected" ์ด ๋๋๋ก ํด์ฃผ์ด์ผํ๋ค.
useEffect(()=>{
setPop("selected");
return()=>{
setPop("")
}
},[idx])
ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์์, ๋์ ์ style, ๋์ ํ style์ ์์๋๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํด์
setPop(""); setPop("selected"); ์์ผ๋ก ์ฝ๋๊ฐ ์คํ์ด ๋์ด์ผ ํ๋ค.
ํ์ง๋ง ์ด๋ค์ ๋ถ์ฌ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ ๋๋ก ๋์ํ์ง ์๋๋ค.
๋ฐ๋ผ์ clean up function์ ์ด์ฉํ๋ฉด useEffect ๋ด๋ถ ์ฝ๋ ์ง์ ์ setPop("")์ ๋จผ์ ์คํํ ๋ค,
useEffect ๋ด๋ถ์์ setPop("selected")๋ฅผ ์คํํ ์ ์๋ค!
์ด๋ ๊ฒ๋ง ํ๋ค๋ฉด ์ญ์๋ ๋์ํ์ง ์๋๋ค..
setTimeout ๋ฑ์ ์ด์ฉํด ์๊ฐ์ฐจ๋ฅผ ๋์ด state ๋ณํ๋ฅผ ์ฃผ์ด์ผํ๋ค.
useEffect(()=>{
setTimeout(() => {
setPop("selected");
}, 100);
return()=>{
setPop("")
}
},[idx])
์ด๋ React18์ ๋์จ ์ ๊ธฐ๋ฅ์ธ automatic batching ๋๋ฌธ์ธ๋ฐ,
์ด๋ก ์ธํด state๋ฅผ ํ๋ฒ์ ์ฐ๋ฌ์์ ๋ณ๊ฒฝํ๋ ค๊ณ ํ ๋, ๋ชจ๋ state๋ฅผ ๋ณ๊ฒฝํ ํ ๋ง์ง๋ง์ ํ๋ฉด์ด ์ฌ๋ ๋๋ง๋๋ค.
(setPop(""); setPop("selected");๋ฅผ ๋ถ์ฌ์ ์ฐ๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์๋ ์ด์ )
๊ทธ๋ ๊ธฐ์ ""์ผ๋ก์ ์ค์ ๊ณผ "selected"๋ก์ ์ค์ ์ ๋ถ๋ฆฌ์์ผ์ฃผ์ด์ผํ๋ค.
โป flushSync ํ์ฉํ๊ธฐ
import { flushSync } from "react-dom" useEffect(()=>{ flushSync(()=>{setPop("");}) setPop("selected") },[idx])
setTimeout ๊ณผ cleanup function์ ์ด์ฉํ๋ ๋ฐฉ๋ฒ ์ธ์๋
flushSync()๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ด๋ aysnc await ์ฒ๋ผ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ๋๊ธฐ์ ์ผ๋ก ๋ง๋ค์ด์
react์ ๋ฆฌ๋ ๋๋ง์ ๊ฐ์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค!
- ๊ฒฐ๊ณผ
๋๊ธ