๋ถ๋ช ๋ค ๋ง๋ค์์ง๋ง, ๋ณด๊ธฐ์ ํํ ๊น๋นก์ ํ์!!
์ด ๊ธ์์ ๋ ๊ฐ์ง ๊น๋ฐํ ํ์์ ๋ํด ๋ค๋ฃฐ ๊ฒ์ด๋ค.
1. useEffect ํธ์ถ์ ์ํ ๊น๋นก์
2. API ํธ์ถ์ ์ํ ๊น๋นก์
1. UseEffect ํธ์ถ์ ์ํ ๊น๋นก์
const [duckUrl, setDuckUrl] = useState('');
useEffect(() => {
setDuckUrl('/duck.png');
}, []);
<img alt='duck' src={duckUrl} />
Hook Flow์ ์ํ๋ฉด DOM ๋ฐฐ์น → ํ์ธํธ ์์ → useEffect ํธ์ถ ์์๋ฅผ ๋ฐ๋ฅธ๋ค.
๋ฐ๋ผ์ useEffect๋ก ์ดํ ํ์ธํธ ์์ ์ด ํ ๋ฒ ๋ ์ด๋ฃจ์ด์ง์ ๋ฐ๋ผ(๋ฆฌํ์ธํธ) ๊น๋นก์ด๋ ํ์์ด ๋ํ๋๋ค.
2. UseLayoutEffect ์ ํตํ ํด๊ฒฐ
const [duckUrl, setDuckUrl] = useState('');
useLayoutEffect(() => {
setDuckUrl('/duck.png');
}, []);
<img alt='duck' src={duckUrl} />
DOM ๋ฐฐ์น → useLayoutEffect →ํ์ธํธ ์์
์ฒซ ํ์ธํธ ์์ ์ด ๋ฐ์ํ๊ธฐ ์ ์ useLayoutEffect ํจ์๊ฐ ํธ์ถ๋๊ธฐ ๋๋ฌธ์, ๊น๋ฐ์ ์์ด DOM์ ์ ๋ฐ์ดํธ ํ ์ ์๋ค.
3. API ํธ์ถ์ ์ํ ๊น๋นก์
์ด์ API ํธ์ถ์ ์ํ ๊น๋นก์ธ ํ์์ ์์๋ณด์.
API ํธ์ถ์ ํตํด ์ด๋ฏธ์ง URL์ ๋ฐ์์ค๊ณ , ๊ทธ URL์ ์ด๋ฏธ์ง ์์ค์ ๋ฃ์ผ๋ฉด ๋ณดํต ๋ค์๊ณผ ๊ฐ์ด ๋ํ๋๋ค.
๋ณด๊ธฐ๋ง ํด๋ ์์ฐํด์ง๋ ๋ฒ๋ฒ ๊ฑฐ๋ฆผ์ด๋ค.
์ค๋ฆฌ๊ฐ ๋์ค๊ธฐ๊น์ง imgํ๊ทธ๊ฐ ๋ณด์ฌ์ง๋ ๊ณผ์ ์ ๋๋ต ์ด๋ ๋ค.
1. alt๊ฐ๊ณผ ์ด๋ฏธ์ง ๋ก๋ ์คํจ ์์ด์ฝ์ด ๋ฌ๋ค. (API ํธ์ถ์ ํตํด url์ ๋ฐ์์ค๊ธฐ ์ )
2. alt๊ฐ๊ณผ ์ด๋ฏธ์ง ๋ก๋ ์คํจ ์์ด์ฝ์ด ์์ด ๋น ํ๋ฉด์ด ๋ฌ๋ค. (์ด๋ฏธ์ง ์์ค์ url์ด ์๊ธฐ๊ธฐ ๋๋ฌธ)
3. ๋ฒ๋ฒ ๊ฑฐ๋ฆฌ๋ฉด์ ๋ถ๋ฌ์์ง๋ค. (์ธ๋ถ url๋ก ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ)
const [duckUrl, setDuckUrl] = useState('');
useEffect(() => {
const getDuck = async () => {
const {
data: { url },
} = await axios.get('https://random-d.uk/api/random');
setDuckUrl(url);
};
getDuck();
}, []);
<img alt="duck" src={duckUrl} />
4. ํด๊ฒฐ๊ณผ์ (1) url์ด ์ค๋น๋๋ฉด imgํ๊ทธ ๋๋๋ง
1๋ฒ ๊ณผ์ " alt๊ฐ๊ณผ ์ด๋ฏธ์ง ๋ก๋ ์คํจ ์์ด์ฝ์ด ๋ฌ๋ค." ์ ์์ ํ๋ค.
API ํธ์ถ์ด ๋๋ ์ง์ ์ ๊ธฐ์ ์ผ๋ก ์กฐ๊ฑด๋ถ ๋๋๋ง์ ์์ผ์คฌ๋ค.
ํ์ง๋ง ์ญ์ ๋ง์กฑ์ค๋ฝ์ง ์๋ค.
์ปคํผ์ฒ๋ผ ๋ถ์์ฐ์ค๋ฝ๊ฒ ๋ด๋ ค์ค๋ ์ฌ์ง์ ๋ณด๊ณ ์์๋ ๋ง์์ด ์๋ ค์จ๋ค...
const [duckUrl, setDuckUrl] = useState('');
const [loaded, setLoaded] = useState(false);
useEffect(() => {
const getDuck = async () => {
const {
data: { url },
} = await axios.get('https://random-d.uk/api/random');
setDuckUrl(url);
setLoaded(true);
};
getDuck();
}, []);
{ loaded &&
<img alt='duck' src={duckUrl} />
}
5. ํด๊ฒฐ๊ณผ์ (2) ์ฌ์ง์ด ๋ค ๋ก๋๋๋ฉด, ๊ทธ๋ ๋๋๋ง ํ๊ธฐ
img ํ๊ทธ์ onLoad ์ด๋ฒคํธ๋ฅผ ํตํด, ์ด๋ฏธ์ง ๋ก๋๊ฐ ๋ ๋ ์กฐ๊ฑด๋ถ ๋๋๋ง์ ์์ผ์คฌ๋ค.
์ถ๊ฐ๋ก loaded ๋์ง ์์๋ค๋ฉด display:none์ ํตํด ๋ฒ๋ฒ ๊ฑฐ๋ฆฌ๋ ๊ณผ์ ์ ๋ณด์ฌ์ง์ง ์๊ฒ ์ค์ ํ๋ค.
์ด๋์ ๋ ํด๊ฒฐ์ด ๋ค ๋์ง๋ง, ์์ฌ์ด ์๊ธด๋ค.
์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ์ค์ด๋ผ๋ ๊ฒ์ ํํํ๊ณ ์ถ๋ค.
const [duckUrl, setDuckUrl] = useState('');
const [loaded, setLoaded] = useState(false);
useEffect(() => {
const getDuck = async () => {
const {
data: { url },
} = await axios.get('https://random-d.uk/api/random');
setDuckUrl(url);
};
getDuck();
}, []);
<img alt='duck'
src={duckUrl}
onLoad={() => setLoaded(true)}
style={loaded ? { display: "block" } : { display: "none" }}
/>
6. ํด๊ฒฐ : skeleton image loading ํจ๊ณผ ์ฃผ๊ธฐ
์ฑ๊ณต! ๊ธฐ๋ฅ๋ง ์ถ๊ฐํ์ ๋ ๋ณด๋ค ํจ์ฌ UX๊ฐ ์ข์์ก๋ค.
์ด๋ฏธ์ง ํ๊ทธ์ ๋ถ๋ชจ ํ๊ทธ์ Background-color์ ์ค์ผ๋ ํค css ํจ๊ณผ๋ฅผ ์ฃผ์ด ๊ตฌํํ๋ค.
์ถํ์ ๊ด๋ จ ๋ก์ง์ ๋ฐ๋ก ์ถ์ถํ๊ณ , ์ค์ผ๋ ํค ๋ก๋ฉ์ ์ฌ์ฉํ๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ด์ํ๊ธฐ ์์ํ๊ฒ ๋ฆฌํฉํ ๋ง์ ํด์ค์ผ๊ฒ ๋ค.
import axios from 'axios';
import { useLayoutEffect, useEffect, useState } from 'react';
import './skeleton.css';
function App() {
const [loaded, setLoaded] = useState(false);
const [duckUrl, setDuckUrl] = useState('');
useLayoutEffect(() => {
const getDuck = async () => {
const {
data: { url },
} = await axios.get('https://random-d.uk/api/random');
setDuckUrl(url);
};
getDuck();
}, []);
return (
<div style={{ backgroundColor: 'black' }}>
<div style={{ width: 500, height: 500 }} className='skeleton'>
<img
alt='duck'
src={duckUrl}
style={loaded ? { display: 'block' } : { display: 'none' }}
onLoad={() => setLoaded(true)}
/>
</div>
</div>
);
}
export default App;
:root {
--loading-grey: #ededed;
}
img {
display: block;
width: 500px;
height: 500px;
}
.skeleton {
background-color: #ededed;
background: linear-gradient(
100deg,
rgba(255, 255, 255, 0) 40%,
rgba(255, 255, 255, 0.5) 50%,
rgba(255, 255, 255, 0) 60%
);
background-size: 200% 100%;
background-position-x: 180%;
animation: 1s loading ease-in-out infinite;
}
@keyframes loading {
to {
background-position-x: -20%;
}
}
'๐ Front > โ๏ธ React JS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React-19 useActionState ์ดํด๋ณด๊ธฐ (0) | 2024.05.26 |
---|---|
virtual DOM ํํค์น๊ธฐ (0) | 2021.12.09 |
React [๋ฆฌ๋ ๋๋ง ๊ณผ์ ] (0) | 2021.09.08 |
[JSX]: JS์ JSX ํ์ฅ์๋ ๋ฌด์์ด ๋ค๋ฅผ๊น? (0) | 2021.09.07 |
[styled-components] ํ์ ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉํ๊ธฐ (0) | 2021.09.02 |