์ด๋๋ง ํ๋ก ํธ VOD๊ฐ ๋๋๊ฐ๊ณ ์๋ค..
์ค๋๋ถํฐ ๋ฆฌ์กํธ ํ์ต์ ์์ํ๋ค!
React vs Javascript
๋ฆฌ์กํธ๋ HTML๊ณผ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ํผํฉํด์ ์ฌ์ฉํ ์ ์๋ JSX๋ฅผ ์ฌ์ฉํ๋ฉฐ, ๋ช ๋ นํ์ธ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ๋ฌ๋ฆฌ, ์ ์ธํ์ผ๋ก์จ UI state๋ง ์ค์ ํด์ฃผ๋ฉด, ๊ณผ์ ์ ์์์ ํด์ค๋ค!
JSX
JSX(JavaScript XML)๋ ๋ฆฌ์กํธ(React)์์ ์ฌ์ฉ๋๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ํ์ฅ ๋ฌธ๋ฒ์ด๋ค.
HTML๊ณผ ๋น์ทํ๊ฒ ์๊ฒผ์ง๋ง, ์ค์ ๋ก๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ณํ๋์ด ์คํ๋ฉ๋๋ค. JSX๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ๋ก ์ฝ์ ์ ์๋๋ฐ, ๋ธ๋ผ์ฐ์ ์ ๋๋ฌํ๊ธฐ ์ ์ ๊ฐ๋ฐ์๋ฒ์์ ์ฌ์ฉ๊ฐ๋ฅํ ์ฝ๋๋ก ๋ณํ๋๋ค.
JSX๋ ํธ๋ฆฌ ๋ชจ์์ ์ฝ๋ ๊ตฌ์กฐ๋ก ๋ฆฌ์กํธ์๊ฒ ๊ฐ ์ปดํฌ๋ํธ๋ค์ด ์ด๋ป๊ฒ ์ฐ๊ด๋์ด ์๊ณ , UI๋ ์ด๋ป๊ฒ ๋ณด์ฌ์ ธ์ผ ํ๋์ง ์๋ ค์ค๋ค. ๊ทธ๋ฆฌ๊ณ , ์ค์ DOM์ ์ ์ดํ๋ฉฐ ํ์ผ ๊ตฌ์กฐ/์ฝ๋๋ฅผ ๋ฐ์ํ๋ค.
Component
๋ฆฌ์กํธ์์ ์ปดํฌ๋ํธ(Component)๋ UI๋ฅผ ๊ตฌ์ฑํ๋ ๊ธฐ๋ณธ ๋จ์๋ก, ๋ ๋ฆฝ์ ์ด๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ์กฐ๊ฐ์ผ๋ก, ํ๋ฉด์ ํน์ ๋ถ๋ถ์ ๋ํ๋ ๋๋ค. ๋ฆฌ์กํธ๋ ์ด๋ฌํ ์ปดํฌ๋ํธ๋ค์ ์กฐํฉ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค!
- ์ปดํฌ๋ํธ๋ช ์ ํ์ค์นผ ์ผ์ด์ค(Pascal Case)์ ์ฌ์ฉํ์ฌ ์์ฑํด์ผํ๋ค.
- ๋ ๋๋ง๋ JSX(HTML ๋งํฌ์ )์ return๊ฐ์ผ๋ก ๋ฐํํ๋ค.
//main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
zzimport './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
๋ฆฌ์กํธ๋ UI๋ฅผ ๋ง๋ค๋, ์ต์์ ์ปดํฌ๋ํธ(App) ํ๋๋ง ๋๊ณ , main.jsx์์ ์ถ๋ ฅ๋๋๋ก ํ๋ค.
(StrictMode: ๊ฐ๋ฐ ํ๊ฒฝ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๊ฐ์งํ๊ณ ๊ฒฝ๊ณ ๋ฅผ ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋๊ตฌ)
๐๐ป React build → Component build → JSX์ฝ๋ ๋ฐํ(by component)
props
๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ฐ์ฒด์ด๋ค.
๋ง์น ํจ์์ ๊ฐ ๋ค๋ฅธ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฃ์ด์ ๋ค๋ฅธ๊ฐ์ด ๋ฆฌํด๋๊ฒ ๋์ํ๋ ๊ฒ์ฒ๋ผ, props๋ฅผ ์ด์ฉํ๋ฉด, componet์ ๊ฐ ๋ค๋ฅธ prop์ ๋ฃ์ด์ ์ ๋ฌํ ์ ์๋ค.
๋ค์ํ ๋ฐฉ์์ผ๋ก prop์ ๋ฐ์ ์ฌ์ฉํ ์ ์๋ค
children
๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ ์์ฑ ์ค ํ๋๋ก, ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ์๊ฒ ์ ๋ฌ๋๋ ํน๋ณํ ์์ฑ์ด๋ค
<Button>Component</Button>
โ๏ธ์ปดํฌ๋ํธ์ ์์ ํ๊ทธ์ ์ข ๋ฃ ํ๊ทธ ์ฌ์ด์ ์์ฑ๋ ๋ด์ฉ(Component)=children์ ๊ฐ์ด๋ค!
// ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ์ ๋ฌธ์์ด์ ์ ๋ฌํ๋ ์์
const ParentComponent = () => {
return (
<ChildComponent>
Hello, I am passed as a child!
</ChildComponent>
);
};
// ์์ ์ปดํฌ๋ํธ์์ children ์์ฑ์ ์ด์ฉํ์ฌ ์ ๋ฌ๋ฐ์ ๋ด์ฉ์ ์ถ๋ ฅํ๋ ์์
const ChildComponent = (props) => {
return (
<div>
<p>Content from children prop:</p>
{props.children}
</div>
);
};
โ๏ธ๊ธฐ๋ณธ์์ฑ์ด๋ฏ๋ก, ๋ค๋ฅธ ์ฌ์ฉ์ ์ ์ prop๊ณผ๋ ๋ค๋ฅด๊ฒ ๋ฐ๋ก ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ๋ช ์ํ์ง ์์๋, ๋ฐ๋ก ์์์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ ์๋ค.
children์ ํด๋น๋๋ ๊ฐ์ ParentComponentํ๊ทธ ์์ ๋ด๊ธด ๊ฐ์ ์์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ ์๊ฒ๋๋ค.
'Hello, I am passed as a child!' ={props.children}
useState
useState๋ ๋ฆฌ์กํธ์์ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ํ (Hook) ์ค ํ๋๋ก, ํจ์ํ ์ปดํฌ๋ํธ์์ ์ํ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค. useState๋ ์ํ ๋ณ์์ ํด๋น ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ํจ์๋ฅผ ๋ฐํํ๋ค. ๋ฆฌ์กํธ์์ ์ฒ๋ฆฌ๋๋ ๋ณ์๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
โ๏ธ์ปดํฌ๋ํธ ํจ์๋ ํญ์ ๊ธฐ๋ณธ์ ์ผ๋ก 1๋ฒ๋ง ์คํ๋๋ค. ๋ฐ๋ผ์, ๊ธฐ์กด์ UI๋ฅผ ์ ๋ฐ์ดํธ ํ๊ธฐ์ํด์ , ๋ฆฌ์กํธ์ ์ํด ์ฌํ๊ฐ ๋์ด ๋ค์ ์ปดํฌ๋ํธ ํจ์๊ฐ ์ฌ์คํ ๋์ด์ผ ํ๋๋ฐ, ์ด๊ฒ์ state๋ฅผ ํตํด ํด๊ฒฐํ ์ ์๋ค!!! ๊ทธ๋์, ๋ณ์๊ฐ ์๋ state๋ก ๊ด๋ฆฌํ๋ค!
์ฆ, state์ ๋ฑ๋กํด๋์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋๋ค๋ฉด, ๋ฆฌ์กํธ๊ฐ UI ์ ๋ฐ์ดํธ (์ปดํฌ๋ํธ ํจ์ ์ฌ์คํ)ํ๋ค.
const stateData=useState();
stateData[0] //current value
stateData[1] //state updating function
useState๋ ๋ฐฐ์ด์ ๋ฐํํ๋๋ฐ, ํ์ฌ์ํ(value) , ์ํ ์ ๋ฐ์ดํธ ํ๋ ํจ์๋ก ๊ตฌ์ฑ๋์ด ์๊ณ ๊ตฌ์กฐ๋ถํด ํ ๋น์ ์ฌ์ฉํด์
const [state,setState]=useState('')
์ด๋ ๊ฒ ์ฌ์ฉํ๋ค!
๐ค ์ ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ useState๋ฅผ ์ฌ์ฉํด์ผ ํ ๊น?
๊ธฐ๋ณธ์ ์ผ๋ก ์ปดํฌ๋ํธ ํจ์๋ ์ฒ์ ํ๋ฒ๋ง ํธ์ถ๋์ด ํ๋ฉด์ ์ถ๋ ฅ๋๋ค. ๊ทธ๋์ ์์ ๊ฐ์ด useState๊ฐ ์๋ ๋ณ์๋ก ์ํ๊ด๋ฆฌ๋ฅผ ํ๋ค๋ฉด, ๋ณ์๊ฐ์ด ์ฌํ ๋น๋์ด ๊ฐ์ด ๋ฐ๋๋ค๊ณ ํด๋ JSX์์์ ์ฌ์ฉ๋๋ ๋ณ์(enteredBody)๊ฐ์ ์ ๋ฐ์ดํธ ๋์ง ์๋๊ฒ!
๐ก
useState์ ์ํ ์ ๋ฐ์ดํธ ํจ์๋ฅผ ํธ์ถํ๋ฉด , ๋ฉ๋ชจ๋ฆฌ์ ์๋ก์ด ์ํ ๊ฐ์ ์ ์ฅํ๊ณ , ๋ฆฌ์กํธ๊ฐ ์ปดํฌ๋ํธ ํจ์๋ฅผ ๋ค์ ํธ์ถํ๋ค.
๊ทธ๋์! ํ์ฌ ์ํ์ ๊ฐ์ ์ฐธ์กฐํ ์ ์๋๊ฒ!!
(์ํ ์ ๋ฐ์ดํธ ํจ์๋ฅผ ํธ์ถํ ๋, ๋ฆฌ์กํธ๋ ์ํ ์ ๋ฐ์ดํธ ์ค์ผ์ค์ ์กฐ์ ํ๋ฉด์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์คํํ๋ค)
์ฆ, JSX์ฝ๋์ ๊ฐ์ฅ ์ต์ ๋ฒ์ ์ค๋ ์ท์ ๊ฐ์ง๊ณ ๋์ธ ์ ์๋๊ฒ์ด๋ค! (UI update)
(์ฐธ๊ณ ๋ก, ๋ฆฌ์กํธ๋ ์ค๋ ์ท์ ๋น๊ตํ์ฌ ์ฐจ์ด๊ฐ ๋๋ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธ๋ฅผ ํ๊ธฐ ๋๋ฌธ์, DOM์ ์ผ๋ถ๋ง์ ์ ๋ฐ์ดํธ ํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ๋ฉด์์ ์ฐ์ํ๋ค)
์ํ ์ฌ๋ฆฌ๊ธฐ
๋ถ๋ชจ์์ ์์์ด ์๋๋ผ, ์์์์ ๋ถ๋ชจ๋ก ์ํ๋ฅผ ์ฌ๋ฆฌ๊ณ ์ถ์ ์ํ์ ๋ํ ์์๋ฅผ ๋ค๋ฃจ์๋ค.
์ปดํฌ๋ํธ๊ฐ PostList > NewPost > Post ์ ํ์ ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์ด ์๋๋ฐ,
NewPost์ textarea์ changeEvent๋ฅผ ํตํด ์ป๋ value(์ ๋ ฅ๊ฐ)์ PostList์ ๋๊ฒจ, ํด๋น ์ ๋ ฅ๊ฐ์ ์ถ๋ ฅํด์ผ ํ๋ค.
→ props์ ์ ์๋ ๋ถ๋ชจ์์ ์์์ด๋ฏ๋ก, ์์์ ์ด๋ฒคํธ ํธ๋ค๋ง์ ํด์ผํ ๊ฒ์ด ์๋๋ผ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์ํ๊ด๋ฆฌ, ์ด๋ฒคํธํธ๋ค๋ง ํจ์๋ฅผ ๋ง๋ค๊ณ ์ด๊ฒ์ ์์ ์ปดํฌ๋ํธ์๊ฒ ๋๊ฒจ์ค์ผ ํ๋ค.
//PostList.jsx (๋ถ๋ชจ)
function PostList() {
const [enteredBody, setEnteredBody] = useState("");
const [enteredAuthor, setEnteredAuthor] = useState("");
function bodyChangeHandler(event) {
setEnteredBody(event.target.value);
}
function authorChangeHandler(event) {
setEnteredAuthor(event.target.value);
}
return (
<>
<NewPost
onBodyChange={bodyChangeHandler}
onAuthorChange={authorChangeHandler}
/>
<ul className={classes.posts}>
<Post author={enteredAuthor} body={enteredBody} />
<Post author="Manuel" body="Check out the full course!" />
</ul>
</>
);
}
export default PostList;
//NewPost.jsx (์์)
function NewPost(props) {
return (
<form className={classes.form}>
<p>
<label htmlFor="body">Text</label>
<textarea id="body" required rows={3} onChange={props.onBodyChange} />
</p>
<p>
<label htmlFor="name">Your name</label>
<input type="text" id="name" required onChange={props.onAuthorChange} />
</p>
</form>
);
}
export default NewPost;
change์ด๋ฒคํธ์ ๋ฐ๋ผ ๊ฐ์ง๋๋ ๊ฐ์ useState์ ์ํ ์ ๋ฐ์ดํธ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ, state๋ฅผ ๊ด๋ฆฌํด์ฃผ๊ณ ๋๋ ์์ ์ปดํฌ๋ํธ(NewPost)์์ ์ด๋ฒคํธํธ๋ค๋ง๋ prop์ผ๋ก ๋ฐ์์ค๊ณ , state๋ ๋ฐ์์์ผํ๋? ํ๋๋ฐ.....? ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ์ฐ๊ฒฐํด๋ ๊ฐ๋ฅํ๋ค?!?๐ต๐ซ
๐กprop์ผ๋ก ์์์๊ฒ ๋๊ฒจ์ค ํจ์๊ฐ useState๋ฅผ ์ ๋ฐ์ดํธ ํ ์ ์๋ ํจ์์ด๊ธฐ ๋๋ฌธ์, ์ํ๊ด๋ฆฌ๋ ๋ถ๋ชจ์์ ํ๊ณ , ์ํ๋ณ๊ฒฝ ๊ฐ์ง?&์ ๋ฐ์ดํธ๋ฅผ ์์์ด ํ๋๊ฒ์ด๋ค.
CSS ๋์ ์คํ์ผ๋ง
prop์ผ๋ก ์ฌ์ฉํ์ฌ class๋ฅผ ๋์ ์ผ๋ก ์ ์ดํ์ฌ ์คํ์ผ๋ง์ ํ ์ ์๋ค
List ๋ฐ์ดํฐ ๋์ ์ถ๋ ฅ
ํ๋์ฝ๋ฉ์ผ๋ก 4๊ฐ์ ์์๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ, map ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ์ถ๋ ฅํ๋ค.
์ ์ง๋ณด์์ ์ฉ์ดํ๊ธฐ ๋๋ฌธ์, ์ด๋ ๊ฒ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋๊ฒ์ด ์ข๋ค!
โ๏ธ๊ฐ ์์๋ฅผ ๊ตฌ๋ถ์ง๊ณ , ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด key์์ฑ์ ๋ฃ์ด์ค์ผํ๋ค. (๋์์ ๋ฌธ์ ๊ฐ์์ง๋ง)