๐ฅ [Conference] React19 2๋ ๋ง์ ์ ๋ฐ์ดํธ, ๋ญ๊ฐ ๋ฌ๋ผ์ง๊น (GDSC Kprintf)
ํด๋น์๋ก๋ GDSC ์ปจํผ๋ฐ์ค์ ์ฐธ์ฌํ์ฌ ๋ค์ ๊ฐ์ ๋ด์ฉ ์๊ฐ์ ๋ฐํ์ผ๋ก
์์ฑ ๋ ํฌ์คํธ ์ ๋๋ค.
๊ฐ์
ํ๋ก ํธ์ค๋ ๊ฐ๋ฐ์๋ฅผ ์ค๋นํ๋ ๋๋ก์ ์ต๊ทผ๋ค์ด Next 14 ์ ๋ฐ์ดํธ๋ ์์ฃผ ํฐ ์ถฉ๊ฒฉ์ด์๋ค.
ํ์ฌ ๋ฆฌ์กํธ ๋ฒ์ ์ 18 ์ด๊ณ , ๊ณต์ ์ ๋ฐ์ดํธ๋ 2022๋ 6์ ์ดํ๋ก ์์๋ค.
2๋ ๋์ ์๋ฌด๊ฒ๋ ์๋ ๊ฒ์ ๊ต์ฅํ ์์ฌ์ด ๋ถ๋ถ์ด์๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ฒ์๋ React ๋ 19 ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ ์์์ด ๋ค๋ ค์ค๋ค๋โฆ
๊ณผ์ฐ ๋ญ๊ฐ ๋ฌ๋ผ์ก์๊น ์์๋ณด์
์ React ๋ ์ ๋ฐ์ดํธ๋ฅผ ํ๋๊ฐ?
- ์ด์ ๋ฆฌ์กํธ๋ ๋ชจ๋ ํ๊ฒฝ์์ ํธํ๋๋ฉฐ
Asset loading
, ๋ฉํ ๋ฐ์ดํฐ ์กฐ์๋ฑ ํฐ ์กฐ์ ์ด ์์ ์์ ์ด๋ผ๊ณ ํ๋ค. - ์ ์ ๋ฆด๋ฆฌ์ฆ ์ Web Components ์ง์๊ณผ ๊ฐ์ ํฐ ๋ณ๊ฒฝ์ด ์๊ณ ๋์๋ค.
๊ทธ๋ผ ์ด์ ๋ณ๊ฒฝ์ด ๋ ์ ์ ํ๋ฒ ์์๋ณด์
๋ณ๊ฒฝ ๋ ์
๊ทธ๋ ๋ค๋ฉด React 19 ์์๋ ๋ฌด์จ ๋ณ๊ฒฝ์ ์ด ์๊ธธ๋ 2๋ ์ด๋ผ๋ ์ธ์์ด ๊ฑธ๋ ธ์๊น?
๋ฆฌ์กํธ๋ ๊ณผ๊ฑฐ์ ํฐ ๋ณ๊ฒฝ์ ์ด ์์๋ค.
- ํด๋์คํ ์ปดํฌ๋ํธ์์ ํจ์ํ ์ปดํฌ๋ํธ๋ก ์ ๋ฐ์ดํธ ๋์ ๋ (19.02.16)
- Concurrent Mode ๋ฅผ ํตํด ์ ์ ์๊ฒ ์ข ๋ ์น์ํ UI ๋ฅผ ์ถ๊ฐ (22.03.09)
๋ฆฌ์กํธ๋ 3๊ฐ์ ๋ ์ด์ด๊ฐ ์๋๋ฐ
Code Layer
: React node ๋ฅผ ํตํ ์ฝ๋ ์ํReact layer
: Virtual DOMBroser layer
: Browser DOM
์ด ๊ตฌ์กฐ๋ฅผ ์ผ๋จ ์์์ผ ๋ณ๊ฒฝ์ ๋ ์ดํดํ๊ธฐ ํธํ๋ค.
๊ณผ๊ฑฐ ๋ณ๊ฒฝ์ฌํญ์ ํ ๋๋ก ์์๋๋ก ํ๋ฌ๊ฐ๋ณด์
์ ํด๋์คํ ์ปดํฌ๋ํธ์์ ํจ์ํ ์ปดํฌ๋ํธ๋ก ๊ตณ์ด ๋ณ๊ฒฝ์ ํ์๊น?
ํจ์ํ ์ปดํฌ๋ํธ๋ ํญ์ ๋๋๋ง๋ ๊ฐ์ UI ์ ๋ณด์ฌ์ค๋ค.
๋ฐ๋ผ์ ์ฌ์ฉ์๋ ๋์ด์ UI ์ ๋ฐ์ดํฐ๊ฐ ๋๊ธฐํ๋ฅผ ์๊ฐํ์ง ์์๋ ๋๊ฒ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React form "react";
class ProfilePage extends React.Component {
showMessage = () => {
alert(user + "๋ฅผ ํ๋ก์ฐ ํฉ๋๋ค.");
};
handleClick = () => {
const {user} = this.props;
// ํจ์๊ฐ ๋ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์์ผ์ผ๋จ...
setTimeout(() => this.showMessage(user), 3000);
}
render() {
return <button onClick = {this.handleClick}>Follow</button>;
}
}
์๋จ์ ์ฝ๋๋ ์์ฃผ ํฐ ๋ฌธ์ ๊ฐ ์๋ค.
ํ๋ฒ ์๊ฐํด๋ณด์
State ๋?
User Interaction ์ผ๋ก ๋ฐ์ํ ๋ฐ์ดํฐ์ ๋ณํ
๋ชจ๋ ๋ฐ์ดํฐ๋ ์๊ธฐ๋ง์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ๋๋ฐ (๋ชจ๋ ํ๋ก๊ทธ๋จ์ ๋ฒ์น)
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ interaction
์ ๋ฐ์ดํฐ๋ ๋
๋ฆฝ์ ์ธ ์๋ช
์ฃผ๊ธฐ๋ฅผ ๋ณด์ฅํด์ผํ๋ค.
1
2
3
4
5
6
7
8
9
function Counter() {
let state = 0;
const onClick = () => {
state++;
};
return <button onClick={onClick}>Click Me</button>
}
์์ ๊ฐ์ re-rendering
๋ ์์๋ ๊ฐ์ด ์๋ ์๋ฉธํ๋ค.
components
๊ฐ ํธ์ถ ๋์ ๋ ์ด๊ธฐํ๊ฐ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
React Hooks
๋ ๋ฆฝ์ ์ธ state ๋ฐ์ดํฐ ์กฐ์์ ๊ฐ๋ฅํ๊ฒ ํ๋ API
1
2
3
4
function Counter() {
const [first, setFirst] = useState(0);
const [second, setSecond] = useState(0);
}
์ผ๋ง๋ ์ง ํจ์๊ฐ ํธ์ถ๋์ด๋ ๋ฐ์ดํฐ๋ฅผ ๋
๋ฆฝ์ ์ธ ๊ฐ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ React
์ Hook
์ด๋ค.
ํ์ง๋ง ๋ค๋ฅธ state
๋ค์ Hooks
๋์ง ๋ชปํ ๊ฒ๋ค์ด ์๋๋ฐ
- useSuspense
- useCatch(useThrow)
- useProvider
- useShouldComponentsUpdate
๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ๋ ๋ฆฝ์ ์ด์ง ๋ชปํ๊ธฐ ๋๋ฌธโฆ
Concurrent React (React 18)
์ด์ ๋์ด์ ์ฌ์ฉ์๋ UI ์ ๋ฐ์ดํฐ์ ๋๊ธฐํ๋ฅผ ์๊ฐํ์ง ์์๋ ๋๋ค.
๊ทธ๋ผ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ๋ฅผ ์ธ์ , ์ด๋ป๊ฒ ๋ฌด์์ผ๋ก UI ์ ์๋ฆฌ์ง?
๊ทธ๋ ๋ค๋ฉด ์ธ์ ์๋ฆด์ง React ๊ฐ ์ ํ๊ถ์ ์ฅ๊ณ ์๋ค๊ฐ ํ์ํ UI ๋จผ์ ์ ๋ฐ์ดํธ๋ฅผ ํ ์ ์์ผ๋ฉด ์ข์ง์์๊น?
๋ผ๋ ์ฐ๊ณ ์ง๋ฌธ์ ๋ค๋ค๋ฅผ ์ ์๋๋ฐ ๊ทธ๋ผ ๋์์ฑ
์ ๊ณ ๋ ค๋ฅผ ํด์ผํ๋คโฆ
๋์์ฑ
์ ๋ํด ์์๋ณด์
Concurrency (๋์์ฑ)
์ดํด๋ฅผ ๋๊ธฐ ์ํด ์์๋ฅผ ๋ค์๋ฉด
ํตํ๋ฅผ ์์๋ฅผ ๋ค์ด๋ณด์ ์ง๊ธ ๋ด๊ฐ ์ฒ ์์ ํตํ๋ฅผ ๋ฐ๊ณ ์๋ค๋ฉด, ์ํฌ์ ํตํ๋ฅผ ๋ค์ ์๊ฐ ์๋ค.
๋ด๊ฐ ์ง๊ธ ์ฒ ์์ ์ก๋ด์ ํ๊ณ ์๋๋ฐ, ์ํฌ์ ์ค์ํ ์ ํ๊ฐ ๊ฑธ๋ ค์จ๋ค๋ฉดโฆ
๊ทธ๋ผ ์ฒ ์์ ํตํ๋ ์ค์ํ์ง ์์ผ๋ ์งํ ์ค์ธ ์ฒ ์ ํตํ๋ ์ ๊น ๋ฉ์ถ๊ณ
์ํฌ์ ์ ํ๋ฅผ ๋ฐ๋๊ฒ ๋ฐ์ดํฐ ์์ผ๋ก๋ ์ค์๋๋ฅผ ๋ํ๋ผ ์ ์๋ค.
๋ฐ๋ผ์ ํด๋น ์์๋ฅผ ๋ฐํ์ผ๋ก
setInputValue
์ setSearchResult
๋ฅผ ์ค๋ช
ํ๋ฉด
setInputValue
๊ฐ ๊ฐ์ ๋จผ์ ์ ์ฅ์ ํ๊ณ ๋์ setSearchResult
๋ฅผ ์คํ์ ํด์ผ ํ๋ฏ๋ก
React 18
์์๋ถํฐ๋ ๋
๋ฆฝ์ ์ผ๋ก ์๊ธฐ๋ง์ ์ค์ผ์ค๋ง์ ํ ์ ์์ด์ก๋ค.
ex) Suspenseโฆ
1
2
3
4
5
6
7
8
return (
<Layout> // OK!
<NavBar/> // OK!
<Suspense fallback ={<UsersSkeleton/>}> // WAIT!
<Users/> // FAILED...
</Suspense>
</Layout>
)
์ค์ React
์ ๋ด๋ถ์์๋ Ping
์ ํตํด ๋ ๋๋ง์ ์๋ํด๋ฌ๋ผ ์์ฒญ์ ํ๋ค.
์ด๊ฒ useState()
์์ ๊ตณ์ด ์ปดํฌ๋ํธ๋ฅผ async
์ฒ๋ฆฌํ์ง ์์๋ ๋๋ ์ด์ ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
//Before React18
function onClick() {
setOne(); // rendering
setTwo(); // rendering
setThree(); // rendering
}
//after React18
function onClick() {
setOne(); // waiting three
setTwo(); // waiting three
setThree(); // rendering
}
ํจ์ํ ์ปดํฌ๋ํธ ๋ด์์๋ ์ ์ฉ์ด ๋๋ ๋ถ๋ถ์ด๋ค.
์ปดํฌ๋ํธ ๋์ ๋ถ๋ฆฌ
๊ฐ ์ปดํฌ๋ํธ๊ฐ ์คํ์ด ๋์ด์ผ ํ๋ ๊ณณ์ ๋ค๋ฅธ ๊ณณ์ด์ด์ผ ํ๋ค.
๊ทธ ์ด์ ๋ ๋ฐ๋ก ์ด๋ค ์ปดํฌ๋ํธ๋ ์๋ฒ์ ์ ๊ทผํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผํ๊ณ
State
๋ Client
์ ์กด์ฌํด์ผ ํ๋ฉฐ ๊ฒฐ๊ตญ ์ฌ์ฉ์์ ์ํธ์์ฉํด์ผ ๊ทธ ์๋ฏธ๋ฅผ ๊ฐ๋๋ฐ
๊ทธ๋ผ ์๋ฒ์ ์ ๊ทผํ๋ ์ปดํฌ๋ํธ๋ UI ์ ์ํด ์ฒ๋ฆฌ๋๊ณ , ๋ ํ๋ฒ ์๋ฒ์ ์ํด ์ฒ๋ฆฌ๊ฐ ๋์ด์ผํ๋ค.
๋๋ฒํ๋ ๊ฑด ์์ฒญ ๋นํจ์จ์ ์ด๋ค.
์ด๋ง์ธ ์ฆ์จ
- state ๊ฐ ์๋ ์ปดํฌ๋ํธ๋ client ์์ ๋ค๋ฃฐ ํ์๊ฐ ์๋ค.
- data๊ฐ ์๋ ์ปดํฌ๋ํธ๋ server ์์ ๋ค๋ฃฐ ํ์๊ฐ ์๋ค.
๋ผ๋ ๋ ๊ฐ์ง ํฐ ํ๋ก ํํํ ์ ์๋ค.
๋ฐ๋ผ์ client ์ ์ฃผ์ง ์์๋ ๋๋ ์ปดํฌ๋ํธ๋ฅผ ์ค์ด๋ ๊ฒ์ด ์ฑ๋ฅ ๊ฐ์ ์ ํฐ ๋์์ด ๋๋ค.
React ๊ฐ 19 ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ ๋๋ ๊ฐ์ฅ ํฐ ์ด์ ๋ค.
Server Component
์ ๋ํ ๋ณธ๊ฒฉ์ ์ธ ์ง์์ด ์์์ด ๋๋ค ์ด ๋ง์ด๋ค.
Server Component ๋?
Server Component
๋ ์๋ฒ์์๋ง ์คํ๋๋ ์ปดํฌ๋ํธ๋ก, ์ค์ ํด๋ผ์ด์ธํธ์ ์ฝ๋๊ฐ ์ ๋ฌ ๋์ง์์- DB, ํ์ผ ๋ค๋ฅธ ์๋ฒ ๋ฑ
server-side resource
์ ์ ๊ทผ ํ ์ ์์
Next ์ use server
๊ฐ์ ๋๋
๋ฐ๋ผ์ Suspense ์ ํจ๊ปํ๋ค๋ฉด ์ต์ ํ์ ์ต์ ์ UI ๋ฅผ ์ ๊ณตํ ์ ์์!!!
๋ํ ์ ํ์ ์ธ ๋ก๋ฉ ์๊ฐ์ ๋ณ๋ ฌ์ ์ผ๋ก๋ ๊ฐ์ ์ ํ ์๊ฐ ์์ด์ก๋ค.
๋ฐ๋ผ์ Client
๋ server component ๋ฅผ ์ ํ์๊ฐ ์์ด์ก๊ณ
๊ทธ๋์ ๋ฒ๋ค ์ฌ์ด์ฆ๊ฐ ์์์ง๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง ๊ฐ์ ์ ์์ฃผ ํฐ ๋์์ด ๋์๋ค.
์๋ก์ด React Hook ์ ๋์ ๋ ๊ทธ์ ๋ง๊ฒ ๊ฐ์ ์ด ๋์๋ค.
useFormState()
useFormStatus()
- โฆ
Asset Loading
์ค์ ๋๋๋ง์ React ์ ๋๋๋ง๊ณผ Asset ์ ๋ ๋๋ง ์๋์ ์ฐจ์ด๊ฐ ๋์ ๋ถํธํ๋ค.
๊ทธ ์ฐจ์ด๊ฐ ๊ฐ์ ์ด ๋์๋๋ฐ
์ด๋ค ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋์๋์ง ์์๋ณด์
Resource Hints
Resource Hints
๊ฐ React ๋ด์์ ๋์
์ด ๋์๋ค.
Resource Hint
๋ธ๋ผ์ฐ์ ์๊ฒ ๋ฏธ๋ฆฌ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๋ฏธ๋ฆฌ ๊ฐ์ ์๋ ค์ฃผ๋ ๋ฐฉ์์ผ๋ก
๋๋๋ง ์๋ ๊ฐ์ ์ ์์ฃผ ํฐ ๋์์ด ๋๋ ๋ฐฉ์์ด๋ค.
preconnect
: ๋ฏธ๋ฆฌ ์๋ฒ์ ์ฐ๊ฒฐ๊น์ง ๊ตฌ์ฑ์ ํด TCP Hand-shake ๋ ๋น ๋ฅด๊ฒ ๋ง๋ค์ด์คdns-preconnect
: DNS ์๋ฒ์ ์ ๊ทผ ํ๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ์๋ ค์คpreload
: ํน์ ๋ฆฌ์์ค๊ฐ ์ฐ์ด๋๊ฒ์ด ํ์คํ ๋
๋ฐ๋ผ์ ํด๋น Hint
๋ค์ ํตํด ๋ฏธ๋ฆฌ ๋ฆฌ์์ค๋ค์ ์๊ฒ ๋๋ฏ๋ก
fallback
์ ๋ ๋น ๋ฅด๊ฒ ๊ด๋ฆฌ ํ ์ ์๊ฒ ๋๊ณ ์ด๋ ๊ณง ๋ก๋ฉ์๋ ๊ฐ์ ์ ์์ฒญ๋ ํ์ด ๋๋ค.
๋ง ๊ทธ๋๋ก ์ ๋ณด๋ฅผ ๋ฏธ๋ฆฌ ์๊ฒ ๋๋๊น
Web Components
๋ฆฌ์กํธ๊ฐ ์๋ ๋ค๋ฅธ ํ๊ฒฝ์์๋ Components ๋ผ๋ ๊ฐ๋ ์ ์ฌ์ฉํ ์ ์์๊น?
๋ผ๋ ๋ฐ์์์ ๋ฐ์๋ ์ ๋ฐ์ดํธ๋ก
Svelte
๊ฐ์ ํ๊ฒฝ์์๋ Component
๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ ๊ฒ์ด๋ค.
Use Hook
Use Hook
์ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ ํจ์๋ ๋๊ธฐ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ด์ง๋ค.
๋ฐ๋ผ์ React-Query
์ ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์กดํ ํ์๊ฐ ์์ด์ง๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export async function fetchNote() {
...// fetch data
return data
}
export function Note({id}) {
const note = use(fetchNote(id));
return (<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
</div>)
}
React-Query
์ ๋งค์ฐ ๋น์ทํ๋ค.
Forward Ref ๊ฐ ๋ถํ์ ํด์ง
React
๋ ๋๋๋ง๊ณผ ์๊ด์๋ ๊ฐ์ ๊ฐ๋ฆฌํค๊ธฐ ์ํ useRef
๋ผ๋ ํ
์ด ์๋ค.
์์ ์ปดํฌ๋ํธ์์ ํ์๋ก ref
๋ฅผ ๋๊ฒจ์ค ๋ forward ref
๋ฅผ ์ฌ์ฉํด์ ๋๊ฒจ์ฃผ์ด์ผ ํ๋๋ฐ
๊ทธ ์ด์ ๋ class Component
๋ด ref
๊ฐ์ props
๋ด ๊ณ ์ ํ ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ ํํ๋ Class ์ insatance
์ธ์ง ์ฌ๋ถ๋ฅผ ๋ด๊ณ ์๋๋ฐ ์๋ชปํ๋ฉด
ํด๋์ค ๋ด ๊ฐ์ด ๋ฎ์ด์ฐ์ฌ์ง ์ ์๋ ์ํ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทผ๋ฐ ์ด์ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ ์์ฃผ ์ฌ์ฉ๊ณ function ์ instance ๊ฐ๋ ์ด ์๊ธฐ ๋๋ฌธ์
์ด์ forward ref
๋ ๊ฐ๋
์ด ์๊ณ ์ด์ ๋ ref ๋ฅผ ํ์์ปดํฌ๋ํธ๋ก props ๋ก ๋๊ฒจ ์ค ์ ์๋ค.
๋ง์น๋ฉฐโฆ
์์ง์ pre realize
์ํ๊ธฐ ๋๋ฌธ์ ์์ง์ ๋ณ๊ฒฝ๋ ์ ์๋ ์ํฉ์ด ๋ง์ง๋ง
๊ฐ์ฅ ์ค์ํ ๋ฐฉ๋ฒ์ ํ ์ดํ๋ก์ ํธ๋ก ์ง์ ์ฒดํํด ๋ณด๋ ๊ฒ์ด๋ค.
๊ณต์ ์ฑ๋์ ์์ฃผ ์ฐธ๊ณ ํ๋ฉฐ ์์ผ๋ก ๋ค๊ฐ์ฌ ๋๊ท๋ชจ ์ ๋ฐ์ดํธ
React 19 ์ ๋ํด ์ค๋น๋ฅผ ๊พธ์คํ ํ์