React

์›น ๋ฐ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๋งŒ๋“ค๊ธฐ

React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์กฐ๊ฐ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Thumbnail, LikeButton, ๊ทธ๋ฆฌ๊ณ  Video ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ „์ฒด ํ™”๋ฉด, ํŽ˜์ด์ง€ ๋ฐ ์•ฑ์—์„œ ์ด๋“ค์„ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Video.js

function Video({ video }) {
return (
<div>
<Thumbnail video={video} />
<a href={video.url}>
<h3>{video.title}</h3>
<p>{video.description}</p>
</a>
<LikeButton video={video} />
</div>
);
}

ํ˜ผ์ž์„œ ์ž‘์—…ํ•˜๋“ , ์ˆ˜์ฒœ ๋ช…์˜ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์™€ ํ•จ๊ป˜ ์ž‘์—…ํ•˜๋“ , React๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Š๋‚Œ์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ, ํŒ€, ์กฐ์ง์—์„œ ์ž‘์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์›ํ™œํ•˜๊ฒŒ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ์™€ ๋งˆํฌ์—…์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑํ•˜๊ธฐ

React ์ปดํฌ๋„ŒํŠธ๋Š” JavaScript ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์กฐ๊ฑด๋ถ€๋กœ ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด if ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋ฐฐ์—ด์— map()์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

VideoList.js

function VideoList({ videos, emptyHeading }) {
const count = videos.length;
let heading = emptyHeading;
if (count > 0) {
const noun = count > 1 ? 'Videos' : 'Video';
heading = count + ' ' + noun;
}
return (
<section>
<h2>{heading}</h2>
{videos.map(video =>
<Video key={video.id} video={video} />
)}
</section>
);
}

์ด ๋งˆํฌ์—… ๊ตฌ๋ฌธ์„ JSX ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ React์— ์˜ํ•ด์„œ ๋Œ€์ค‘ํ™”๋œ JavaScript ๊ตฌ๋ฌธ์˜ ํ™•์žฅ์ž…๋‹ˆ๋‹ค. JSX ๋งˆํฌ์—…์„ ๊ด€๋ จ๋œ ๋ Œ๋”๋ง ๋กœ์ง๊ณผ ๊ฐ€๊นŒ์ด ๋‘๋ฉด, React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ  ์œ ์ง€ํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ๊ณณ์— ์ƒํ˜ธ์ž‘์šฉ ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ

React ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ณ  ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ๋ž€์— ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ƒํ˜ธ์ž‘์šฉ์— ์‘๋‹ตํ•˜์—ฌ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ React๋Š” ์ƒˆ ๋ฐ์ดํ„ฐ์™€ ์ผ์น˜ํ•˜๋„๋ก ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

SearchableVideoList.js

import { useState } from 'react';

function SearchableVideoList({ videos }) {
const [searchText, setSearchText] = useState('');
const foundVideos = filterVideos(videos, searchText);
return (
<>
<SearchInput
value={searchText}
onChange={newText => setSearchText(newText)} />
<VideoList
videos={foundVideos}
emptyHeading={`No matches for โ€œ${searchText}โ€`} />
</>
);
}

์ „์ฒด ํŽ˜์ด์ง€๋ฅผ React๋กœ ๋นŒ๋“œํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. React๋ฅผ ๊ธฐ์กด HTML ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ํ•˜๊ณ , ์–ด๋””์—์„œ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด์„œ ํ’€์Šคํƒ์œผ๋กœ ๋งŒ๋“ค๊ธฐ

React๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•จ๊ป˜ ๋ฌถ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ผ์šฐํŒ…๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๊ทœ์ •ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. React๋กœ ์•ฑ์„ ๋งŒ๋“ค๋ ค๋ฉด, Next.js ๋˜๋Š” Remix ๊ฐ™์€ ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

confs/[slug].js

import { db } from './database.js';
import { Suspense } from 'react';

async function ConferencePage({ slug }) {
const conf = await db.Confs.find({ slug });
return (
<ConferenceLayout conf={conf}>
<Suspense fallback={<TalksLoading />}>
<Talks confId={conf.id} />
</Suspense>
</ConferenceLayout>
);
}

async function Talks({ confId }) {
const talks = await db.Talks.findAll({ confId });
const videos = talks.map(talk => talk.video);
return <SearchableVideoList videos={videos} />;
}

React๋Š” ์•„ํ‚คํ…์ฒ˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋˜๋Š” ๋นŒ๋“œ ๋„์ค‘์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ด๋ฅผ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ

์‚ฌ๋žŒ๋“ค์€ ๋‹ค์–‘ํ•œ ์ด์œ ๋กœ ์›น๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋™์ผํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์•ฑ๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์„ ๋ชจ๋‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”Œ๋žซํผ์— ๊ฐ•์ ์„ ํ™œ์šฉํ•˜์—ฌ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์ ํ•ฉํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

example.com

์›น์— ์ถฉ์‹คํ•˜๊ธฐ

์‚ฌ๋žŒ๋“ค์€ ์›น์ด ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๊ธธ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ HTML์„ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜์—ฌ JavaScript ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ๋‚จ์€ ๋‚ด์šฉ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ React๋Š” ํ‘œ์ค€ web API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง ์ค‘์—๋„ UI๋ฅผ ๋ฐ˜์‘์ ์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1:41 AM

๋„ค์ดํ‹ฐ๋ธŒ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ

์‚ฌ๋žŒ๋“ค์€ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์ด ํ”Œ๋žซํผ๊ณผ ๊ฐ™์€ ๋ชจ์–‘์ฒ˜๋Ÿผ ๋Š๊ปด์ง€๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. React Native์™€ Expo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React๋ฅผ ํ†ตํ•˜์—ฌ Android, iOS ๋“ฑ์„ ์œ„ํ•œ ์•ฑ์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UI๋“ค์ด native์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง„์งœ native์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ web view๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. React ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์‹ค์ œ Android, iOS ํ”Œ๋žซํผ์—์„œ ์ œ๊ณตํ•˜๋Š” view๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์›น ๋ฐ ๋„ค์ดํ‹ฐ๋ธŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์˜ ์ €ํ•˜ ์—†์ด ์—ฌ๋Ÿฌ ํ”Œ๋žซํผ์— ์ถœ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ์ง์—์„œ๋Š” ํ”Œ๋žซํผ ๊ฐ„์˜ ๊ฒฉ์ฐจ๋ฅผ ์ค„์ด๊ณ , ๊ธฐ๋Šฅ์„ ์™„์ „ํžˆ ์†Œ์œ ํ•˜๋Š” ํŒ€์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ค€๋น„๋˜๋ฉด ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๊ธฐ

React๋Š” ๋ณ€ํ™”์— ์‹ ์ค‘ํ•˜๊ฒŒ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  React ์ปค๋ฐ‹์€ 10์–ต ๋ช… ์ด์ƒ์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค์— ํฌ๋ฆฌํ‹ฐ์ปฌํ•œ ์˜์—ญ์—์„œ ํ…Œ์ŠคํŠธ ๋ฉ๋‹ˆ๋‹ค. Meta์—์„œ๋Š” 10๋งŒ ๊ฐœ ์ด์ƒ์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ชจ๋“  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „๋žต์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

React ํŒ€์€ ํ•ญ์ƒ React๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์—ฐ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ๋…„์ด ๊ฑธ๋ฆฌ๋Š” ์—ฐ๊ตฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ์—ฐ๊ตฌ ์•„์ด๋””์–ด๋ฅผ ์ œํ’ˆ์— ์ ์šฉํ•˜๋Š” ๋ฐ์— ๋†’์€ ๊ธฐ์ค€์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์ฆ๋œ ์ ‘๊ทผ ๋ฐฉ์‹๋งŒ์ด React ์ผ๋ถ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ˆ˜๋ฐฑ๋งŒ ๋ช…์ด ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ

์—ฌ๋Ÿฌ๋ถ„์€ ํ˜ผ์ž๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. 200๋งŒ ๋ช…์ด ๋„˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด React ๋ฌธ์„œ๋ฅผ ๋งค๋‹ฌ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค. React๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ํŒ€์ด ๋™์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

People singing karaoke at React Conf
Sunil Pai speaking at React India
A hallway conversation between two people at React Conf
A hallway conversation at React India
Elizabet Oliveira speaking at React Conf
People taking a group selfie at React India
Nat Alison speaking at React Conf
Organizers greeting attendees at React India

์ด๊ฒƒ์ด ๋ฐ”๋กœ React๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋„˜์–ด ์•„ํ‚คํ…์ฒ˜, ์‹ฌ์ง€์–ด ์—์ฝ”์‹œ์Šคํ…œ ๊ทธ ์ด์ƒ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค. React๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์ž…๋‹ˆ๋‹ค. ๋„์›€์„ ์š”์ฒญํ•˜๊ณ , ๊ธฐํšŒ๋ฅผ ์ฐพ๊ณ , ์ƒˆ๋กœ์šด ์นœ๊ตฌ๋ฅผ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์™€ ๋””์ž์ด๋„ˆ, ์ดˆ๋ณด์ž์™€ ์ „๋ฌธ๊ฐ€, ์—ฐ๊ตฌ์›๊ณผ ์˜ˆ์ˆ ๊ฐ€, ๊ต์‚ฌ์™€ ํ•™์ƒ์„ ๋งŒ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘์˜ ๋ฐฐ๊ฒฝ์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ, React๋ฅผ ํ†ตํ•ด ํ•จ๊ป˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

React ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ