๐ก ๋ฆฌ์กํธ์์ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ค๋ฅด๊ฒ state๋ฅผ ํ์ฉ (ํญ์ state๋ฅผ ์กฐ์)
๋ฆฌ์กํธ ์ฌ์ฉ ์ด์ : ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์์ / html์ ํจ์,array, object์ ๋ณด๊ดํ๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ(html๊ด๋ฆฌ ํธํจ) / react native๋ฅผ ํตํด ๊ฐ์ ๋ฆฌ์กํธ ๋ฌธ๋ฒ์ผ๋ก ๋ชจ๋ฐ์ผ์ฑ๊ฐ๋ฐ ๊ฐ๋ฅ(html css๋ฌธ๋ฒ๋ง ์ฝ๊ฐ ๋ค๋ฆ)
๊ฐ๋ฐํ๊ฒฝ ์ธํ
nodejs์ค์น โ ์์ ํด๋์์ฑ ํ ํฐ๋ฏธ๋์ด์ด์ npx create-react-app ํ๋ก์ ํธ๋ช โvscode์์ ์ด๊ธฐ
scrํด๋ ์์ App.js์์ ์ฝ๋์์ฑ โ vscodeํฐ๋ฏธ๋์์ npm start๋๋ฅด๋ฉด ์์ฑํ ํ์ด์ง ๋ณด์ฌ์ค
์ปจํธ๋กค+c ๋๋ฅด๋ฉด ์ข ๋ฃ
๊ธฐ์กด html css์ฒ๋ผ ์ฝ๋๋ฅผ ์ง์ง๋ง ๋ฆฌ์กํธ์์๋ html๋์ JSX๋ผ๋๊ฑธ ์ฌ์ฉ
์นํ์ด์ง ๋ ์ด์์์ html์์ ์ง๋๊ฒ์ฒ๋ผ div๋ฐ์ค๋ก ๋๋ ์ ์ฌ์ฉ
css์คํ์ผ์ App.cssํ์ผ์์ ์์ฑ
๐ JSX ๋ฌธ๋ฒ
JSX๋ ์ผ์ข ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ผ์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉํ๋ ์์ฝ์ด์ธ class๋ผ๋ ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์๋จ
href / id / className / src ๋ฑ ์ฌ๋ผ๊ฐ์ง html์์ฑ๋ค์ ๋ฃ์ด์ ์ฌ์ฉ๊ฐ๋ฅ
โ๋ณ์์ ์๋๊ฑธ html์ ๊ฝ์๋ฃ๋ ์์ ์ ๋ฐ์ดํฐ๋ฐ์ธ๋ฉ ์ด๋ผ๊ณ ํจ
style={}์์ {}์๋ฃํ์ผ๋ก ์ง์ด๋ฃ์ด์ผํจ - {์์ฑ๋ช : โ์์ฑ๊ฐโ}
font-size์ฒ๋ผ ๋์ฌ๊ธฐํธ ์ฌ์ฉ ๋ถ๊ฐ โ ์ผ์ข ์ ์๋ฐ์คํฌ๋ฆฝํธ์ด๊ธฐ ๋๋ฌธ์ ๋นผ๊ธฐ๋ก ์ธ์ , ๋ถ์ฌ์ ์๊ธ์๋ฅผ ๋๋ฌธ์๋ก
function App() {
let post = '๋ง์งํฌ์ด';
return (
<div className="App">
<div className="black-nav">
//์ด๋ฌ๋ฉด ํด๋์ค๋ช
์ด ๋ง์งํฌ์ด๊ฐ ๋จ
<h4 className={post} style={{color: 'yellow', fontSize: '16px'}}>BLOG</h4>
</div>
<h4>{post}</h4>
</div>
);
}
state ๋ง๋๋ ๋ฒ
์ ์ผ ์์ import {useState} from โreactโ ํ๊ณ
useState(โ๋ณด๊ดํ ์๋ฃโ) : ์๋ฃ ์ ์ฅ๊ฐ๋ฅ
let [a,b] = useState(โ๋จ์์ฝํธ์ถ์ฒโ); โ a์๋ฆฌ์ state์ด๋ฆ์ ์๋ช ํ๊ณ ์ฌ์ฉ
์๋ฐ์คํฌ๋ฆฝํธ destructuring ๋ฌธ๋ฒ
array์์ ์๋ ๋ฐ์ดํฐ๋ค์ ๋ณ์๋ก ์ฝ๊ฒ ์ ์ฅํ๊ณ ์ถ์๋ ์ฐ๋ ๋ฌธ๋ฒ
let [name, age] = ['Kim', 20] //name์๋ Kim, age์๋ 20
โ ๋ฆฌ์กํธ์์๋ useState()๋ฅผ ์ฐ๋ฉด [๋ฐ์ดํฐ1, ๋ฐ์ดํฐ2] ํํ์ array๊ฐ ๋จ์
๋ฐ์ดํฐ1์๋ฆฌ์ โ๋จ์์ฝํธ์ถ์ฒโ๊ฐ์ ์๋ฃ๊ฐ ์๊ณ
๋ฐ์ดํฐ2์๋ฆฌ์ state๋ณ๊ฒฝ์ ๋์์ฃผ๋ ํจ์๊ฐ ๋ค์ด์์
๐ ๋ณ์๋ง๊ณ state์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ ์ฐ๋ ์ด์
๋ณ์๋ ๋ณ๋์ฌํญ์ด ์๊ธฐ๋ฉด ์๋์ผ๋ก ์ฌ๋ ๋๋งํด์ฃผ์ง ์์ง๋ง
state๋ ๋ณ๋์ฌํญ์ด ์๊ธฐ๋ฉด ์๋์ผ๋ก ์ฌ๋ ๋๋งํด์ค
โ ์ฆ ์์ฃผ๋ณ๊ฒฝ๋ ๊ฒ ๊ฐ์ ๋ฐ์ดํฐ๋ค์ state์ ์ ์ฅํด์ html์ ๋ฐ์ดํฐ๋ฐ์ธ๋ฉ
์ข์์ ๋ฒํผ ๋ง๋ค๊ธฐ
์์ฃผ ๋ฐ๋ ๊ฒ ๊ฐ์ html๋ด์ฉ์ state๋ก ์ ์ฅํ๋ค๊ฐ ๋ฐ์ดํฐ๋ฐ์ธ๋ฉํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ์ข์์ ๊ฐ์๋ฅผ state๋ก ์ฌ์ฉ
onClick ์ฌ์ฉ๋ฒ
1.Click๊ฐ ๋๋ฌธ์
2.{} ์ค๊ดํธ ์ฌ์ฉ
3.์ค๊ดํธ ์์๋ ๊ทธ๋ฅ ์ฝ๋๊ฐ ์๋๋ผ ํจ์๋ฅผ ๋ฃ์ด์ผ ์ ์๋ํจ
onClick={ }์์๋ ๋ง๋ค์ด๋ ํจ์๋ช ์ ์ ๊ฑฐ๋ ํจ์ํ๋๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ ์ง์ด๋ฃ์ด์ผํจ -> ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ธฐ๋๋ฌธ์ ํจ์๋ช ์ ์ ๋๊ฒ ์ข์
state๋ณ๊ฒฝํ๋ ๋ฒ
๋ณ์์ +1ํ ๋ ค๋ฉด ๋ณ์ += 1 ํ๋ฉด ๋์ง๋ง ๋ณ์๊ฐ ์๋ state์ด๊ธฐ ๋๋ฌธ์ state๋ณ๊ฒฝํจ์๋ฅผ ์จ์ผํจ(state์ ์ธ์ ๋๋ฒ์งธ ์๋ช ํ ๊ฒ-set)
function App() {
let [good, setGood] = useState(0);
return (
<div className='list'>
<h4>{ title[0] } <span onClick={ () => { setGood(good+1) }}>์ข์์๐</span> { good } </h4>
<p>today : 2022.11.10</p>
</div>
๊ธ์ ๋ชฉ ๋ณ๊ฒฝ
function App(){
let [title, setTitle] = useState( ['๋จ์์ฝํธ ์ถ์ฒ', '๊ฐ๋จ ์ฐ๋๋ง์ง', 'ํ์ด์ฌ ๋
ํ'] );
return (
<button onClick={ ()=>{
//ํด๋น ์ฝ๋๋ ํ์ฅ์ฑ ๋ถ์กฑ ๊ธ์ ๋ชฉ[0] = '์ฌ์์ฝํธ ์ถ์ฒ'; ์ผ๋ก๋ ๊ฐ๋ฅ
setTitle(['์ฌ์์ฝํธ ์ถ์ฒ', '๊ฐ๋จ ์ฐ๋๋ง์ง', 'ํ์ด์ฌ ๋
ํ'])
} }> ์์ ๋ฒํผ </button>
)
}
setTitle(โ์ฌ์์ฝํธ์ถ์ฒโ)์ผ๋ก ํ๋ฉด ๊ธฐ์กด state๋ฅผ ๊ดํธ์์ ๋ด์ฉ์ผ๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ ๋๋ฌธ์ ์๋จ
๐ array, object ์๋ฃ๋ ๋ณดํต ๊ธฐ์กด๊ฐ์ ๋ณด์กดํด์ฃผ๋์์ผ๋ก ์ฝ๋ฉํจ
function App(){
let [title, setTitle] = useState( ['๋จ์์ฝํธ ์ถ์ฒ', '๊ฐ๋จ ์ฐ๋๋ง์ง', 'ํ์ด์ฌ ๋
ํ'] );
return (
<button onClick={ ()=>{
let copy = [...๊ธ์ ๋ชฉ]; //state๋์์๋ฆฌ๋๋ฌธ
copy[0] = '์ฌ์์ฝํธ ์ถ์ฒ';
setTitle(copy)
} }> ์์ ๋ฒํผ </button>
)
}
state ๋ณ๊ฒฝํจ์ ๋์์๋ฆฌ
state๋ณ๊ฒฝํจ์๋ ๋ณ๊ฒฝํ๊ธฐ ์ ์ ๊ธฐ์กดstate === ์ ๊ทstate๋ฅผ ๋จผ์ ๊ฒ์ฌํ๊ณ
๊ฐ์ผ๋ฉด state๋ณ๊ฒฝ์ ํด์ฃผ์ง์์
array / object ๋์์๋ฆฌ
let data1 = [1,2,3];
let data2 = data1; //๋ณต์ฌ๋ฌธ๋ฒ
let copy = ๊ธ์ ๋ชฉ;
copy[0] = '์ฌ์์ฝํธ ์ถ์ฒ';
๊ธ์ ๋ชฉ๋ณ๊ฒฝ(copy)
//์ด๋ ๊ฒ ํ๋ฉด ๊ธฐ์กด ๊ธ์ ๋ชฉ๊ณผ copy๋ ๊ฐ์ ๊ณณ์ ๊ฐ๋ฆฌํค๊ธฐ๋๋ฌธ์ state๋ณ๊ฒฝ์ ํด์ฃผ์ง์์
spread operator ์ 3๊ฐ ๋ฌธ๋ฒ โฆ
spread operator๋ผ๊ณ ํ๋ ๋ฌธ๋ฒ
array / object์๋ฃํ ์ผ์ชฝ์ ๋ถ์ผ ์ ์์ผ๋ฉฐ ๊ดํธ๋ฅผ ๋ฒ๊ฒจ๋ฌ๋ผ๋ ๋ป
โฆ[1,2,3] ์ 1,2,3์ด ๋จ์
let data1 = [1,2,3];
let data2 = [...data1];
console.log(data1 === data2) //false๋ก ๋์ด
data1์ ์๋ ์๋ฃ๋ค์ ๊ดํธ ๋ฒ๊ธด๋ค์์ ๋ค์ array๋ก ๋ง๋ค๊ฒ๋๋ฉด ๋ค๋ฅธ ์์น๋ฅผ ๊ฐ๋ฆฌํด - ์๋ก์ด array๋ก ์ธ์ โ๋ ๋ฆฝ์ ์ธ array๋ณต์ฌ๋ณธ์ ์์ฑํ ์ ์์
๋ฆฌ์กํธ์์ array/object state๋ฅผ ์์ ํ๊ณ ์ถ์ผ๋ฉด
๋ ๋ฆฝ์ ์ธ ์นดํผ๋ณธ์ ๋ง๋ค์ด์ ์์ ํ๋๊ฒ ์ข์
[...๊ธฐ์กดstate]
{...๊ธฐ์กดstate}
์ด๋ ๊ฒ ํ๋ฉด ๋ ๋ฆฝ์ ์ธ ์นดํผ๊ฐ ํ๋ ์์ฑ
html ์ฝ๋ ์งค ๋ ์ ์์
return() ์์ ๋๊ฐ์ html ํ๊ทธ๋ฅผ ๋๋ํ ์ ์ผ๋ฉด ์๋๋ค
retrun() ๋ด๋ถ๋ ํ๋์ ํ๊ทธ๋ก ์์ํด์ ํ๋์ ํ๊ทธ๋ก ๋๋์ผํจ - ์ ์ฒด๋ฅผ ํ๋์ div๋ก ๋ฌถ์ด์ฃผ๋ฉด ํด๊ฒฐ
return(
<div>
<div></div>
<div></div>
</div>
) //div๋ฅผ ๋๋ํ ์ ๊ณ ์ถ์๋ ์ด๋ ๊ฒ ํจ ->fragment๋ฌธ๋ฒ
//<> </>๋ก๋ ๊ฐ๋ฅ
๐ ๋ณต์กํ html์ ํ ๋จ์ด๋ก ์นํํ ์ ์๋ Component๋ฌธ๋ฒ
์ฃผ๋ก Componentํ ํ๋ ๋ถ๋ถ
function App (){
return (
<div>
(์๋ต)
<Modal></Modal>
</div>
)
}
function Modal(){
return (
<div className="modal">
<h4>์ ๋ชฉ</h4>
<p>๋ ์ง</p>
<p>์์ธ๋ด์ฉ</p>
</div>
)
}
์ถ์ฝํ html ๋ฉ์ด๋ฆฌ๋ฅผ Component๋ผ๊ณ ํจ
Component ๋ง๋ค ๋ ์ฃผ์์
๐ Component ๋จ์
์ผ๋จ HTML ๊น๋ํ๊ฒ ์ฐ๋ ค๊ณ Component๋ฅผ ์๋ฐฑ๊ฐ ๋ง๋ค๋ฉด ๊ทธ๊ฒ ๋ง์ผ๋ก๋ ๊ด๋ฆฌ๊ฐ ํ๋ญ๋๋ค.
์๋ฅผ ๋ค์ด์ function Modal ์์์ ๊ธ์ ๋ชฉ state๋ฅผ ์ฐ๊ณ ์ถ์ด์ {๊ธ์ ๋ชฉ} ์ด๋ ๊ฒ ์ฐ๋ฉด ์ ์๋๋๋ฐ
์๋๋ฉด ๋น์ฐํ ์๋ฐ์คํฌ๋ฆฝํธ์์
ํ function ์์ ์๋ ๋ณ์๋ฅผ ๋ค๋ฅธ function์์ ๋ง๋๋ก ์ธ ์ ์์ด์ ๊ทธ๋ ์ต๋๋ค.
props๋ผ๋ ๋ฌธ๋ฒ์ ์ด์ฉํด state๋ฅผ <Modal>
๊น์ง ์ ํด์ค์ผ ๋น๋ก์ ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค.
๋ฆฌ์กํธ์์ ๋์ ์ธ UI ๋ง๋๋ ๋ฐฉ๋ฒ
JSX์์ ์กฐ๊ฑด๋ฌธ ์ฐ๋ ๋ฒ
JSX์์์๋ if else๋ฌธ๋ฒ์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์
if๋ฌธ๋ฒ๋์ ์ผํญ์ฐ์ฐ์๋ JSX์ค๊ดํธ ์์์ ์ฌ์ฉ๊ฐ๋ฅ
์กฐ๊ฑด์ ? ์กฐ๊ฑด์ ์ฐธ์ผ ๋ ์ฝ๋ : ์กฐ๊ฑด์ ๊ฑฐ์ง์ผ ๋ ์ฝ๋
function App (){
let [modal, setModal] = useState(false);
return (
<div>
(์๋ต)
//setModal(!modal) ํ๋ฉด๋๋ฅด๋ฉด ๋ณด์ด๊ณ ํ๋ฒ ๋ ๋๋ฅด๋ฉด ์๋ณด์ด๊ฒ ๋
<button onClick={ ()=>{ setModal(true) } }> {๊ธ์ ๋ชฉ[0]} </button>
{
modal == true ? <Modal></Modal> : null
}
</div>
)
}
๐ ์๋ฐ์คํฌ๋ฆฝํธ map ํจ์ ์ฐ๋๋ฒ
๋ชจ๋ array์๋ฃ ์ฐ์ธก์ map()ํจ์๋ฅผ ๋ถ์ผ ์ ์์
var arr = [2,3,4];
var newArray = arr.map(function(a){
return a * 10
});
console.log(newArray) //[20, 30, 40]์ถ๋ ฅ
JSX์์์ html์ ๋ฐ๋ณต์์ฑ - map์ ํ์ฉ
function App (){
return (
<div>
(์๋ต)
{
๊ธ์ ๋ชฉ.map(function(a){ //(a,i)๋ก ํ๋ฉด a์๋ array์ ์๋ฃ i๋ 0๋ถํฐ1์ฉ์ฆ๊ฐํ๋ ์ ์
return (
<div className="list" key={i}>
//map ๋ฐ๋ณต๋ฌธ์ผ๋ก ๋ฐ๋ณต์์ฑํ html์ key={i} ์ด๋ฐ ์์ฑ์ ์ถ๊ฐํด์ผํจ
<h4>{ a }</h4>
<p>2์ 18์ผ ๋ฐํ</p>
</div> )
})
}
</div>
)
}
map ๋ฐ๋ณต๋ฌธ์ผ๋ก ๋ฐ๋ณต์์ฑํ html์ key={i} ์ด๋ฐ ์์ฑ์ ์ถ๊ฐํด์ผํจ
map๋ฐ๋ณต์์ฑํ html์์ ๊ฐ๊ฐ ์ข์์ ์ฆ๊ฐ์ํค๊ธฐ
โ array์๋ฃํ์ผ ๊ฒฝ์ฐ ๊ทธ๋ฅ ๋ฐ๊พธ๋ฉด ๊ฐ์ ์์น๋ฅผ ๊ฐ๋ฆฌํค๊ธฐ๋๋ฌธ์ ๋ณ๊ฒฝ๋์ง์์์ ๋ณต์ฌํ๊ณ ์์
<h4>
{ ๊ธ์ ๋ชฉ[i] }
<span onClick={()=>{
let copy = [...๋ฐ๋ด]; //๋ณต์ฌ
copy[i] = copy[i] + 1;
๋ฐ๋ด๋ณ๊ฒฝ(copy) //setGood(copy)
}}>๐</span> {๋ฐ๋ด[i]}
</h4>
์์ ์ปดํฌ๋ํธ์์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ state๊ฐ ํ์ํ ๋
์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๋ค๋ฅธ ํจ์์ ์๋ ๋ณ์๋ฅผ ๋ง์๋๋ก ๊ฐ์ ธ๋ค ์ธ ์ ์์
๋จ ๋ถ๋ชจ-์์๊ด๊ณ์ผ๋๋ ๋ถ๋ชจ์ปดํฌ๋ํธ์ state๋ฅผ ์์์ปดํฌ๋ํธ๋ก ์ ์ก๊ฐ๋ฅ
์์->๋ถ๋ชจ : ๋ถ๊ฐ๋ฅ
function App (){
let [๊ธ์ ๋ชฉ, ๊ธ์ ๋ชฉ๋ณ๊ฒฝ] = useState(['๋จ์์ฝํธ ์ถ์ฒ', '๊ฐ๋จ ์ฐ๋๋ง์ง', 'ํ์ด์ฌ๋
ํ']);
return (
<div>
<Modal></Modal>
</div>
)
}
function Modal(){
return (
<div className="modal">
<h4>{ ๊ธ์ ๋ชฉ[0] }</h4>
<p>๋ ์ง</p>
<p>์์ธ๋ด์ฉ</p>
</div>
)
}
props๋ก ๋ถ๋ชจโ์์ state ์ ์ก๋ฐฉ๋ฒ
function App (){
let [title, setTitle] = useState(['๋จ์์ฝํธ ์ถ์ฒ', '๊ฐ๋จ ์ฐ๋๋ง์ง', 'ํ์ด์ฌ๋
ํ']);
return (
<div>
<Modal setTitle={setTitle}></Modal>
</div>
)
}
function Modal(props){
return (
<div className="modal">
<h4>{ props.setTitle[0] }</h4>
<p>๋ ์ง</p>
<p>์์ธ๋ด์ฉ</p>
</div>
)
}
props๋ ๋ฌดํํ ์ ์ก๊ฐ๋ฅ (์ฌ๋ฌ๊ฐ)
state์ธ์ ์ผ๋ฐ๋ณ์, ํจ์, ์ผ๋ฐ๋ฌธ์(์ผ๋ฐ๋ฌธ์๋ ์ค๊ดํธ์์ด ์ฌ์ฉ)์ ์ก๊ฐ๋ฅ
<Modal ss = {๋ณ์๋ช
} or {ํจ์๋ช
} > <Modal ss = โ๊ฐ๋จ์ฐ๋๋ง์ง>
์์ โ๋ถ๋ชจ ๋ถ๊ฐ๋ฅ / ์์ ์ปดํฌ๋ํธ๋ก๋ ๋ถ๊ฐ๋ฅ โ ๋ฌด์กฐ๊ฑด ๋ถ๋ชจ์์๊ฐ์๋ง ๊ฐ๋ฅ
props๋ ํจ์ ํ๋ผ๋ฏธํฐ ๋ฌธ๋ฒ์ด๋ ๊ฐ์
function Modal(props){
return (
<div className="modal" style={{ background : props.color }}>
<h4>{ props.๊ธ์ ๋ชฉ[0] }</h4>
<p>๋ ์ง</p>
<p>์์ธ๋ด์ฉ</p>
</div>
)
}
์ด๋ ๊ฒ ํด๋์ผ๋ฉด Modal์ฌ์ฉํ๋ ๊ณณ์์
<Modal color={โblueโ}> <Modal color={โyellowโ}>
์ด๋ ๊ฒ ๋๊ฒจ์ฃผ๋ ๊ฐ์ ๋ฐ๊ฟ์ ์ฌ์ฉ๊ฐ๋ฅํจ(ํ๋ผ๋ฏธํฐ์ฒ๋ผ)
<button onClick={() => { props.setTitle(['์ฌ์์ฝํธ์ถ์ฒ', '๊ฐ๋๋ค', '๊ณต๋ถํ๊ธฐ'])}}>๊ธ์์ </button>
์ด๋ฐ์์ผ๋ก ํจ์์์ฒด๋ฅผ ๋๊ฒจ๋ฐ์์ ์ฌ์ฉ๊ฐ๋ฅ
function App(){
let [modalTitle,setModalTitle] = useState(0);{/**๋ชจ๋ฌ ์ฐฝ์์์ title์ ์ธ๋ฑ์ค๋ฅผ ์ํ state */}
h4๋ฅผ ๋๋ฅด๋ฉด setModalTitle(i)
}
function Modal(props) {
return (
<div className="modal" style={{background : props.color}}>
<h4>{props.title[props.modalTitle]}</h4> {/*state๋ฅผ props๋ก ๋๊ฒจ์์ ์ฌ์ฉ */}
<p>๋ ์ง</p>
<p>์์ธ๋ด์ฉ</p>
{/*ํจ์๋ฅผ ๋๊ฒจ๋ฐ์ ์ฌ์ฉ */}
<button onClick={() => { props.setTitle(['์ฌ์์ฝํธ์ถ์ฒ', '๊ฐ๋๋ค', '๊ณต๋ถํ๊ธฐ'])}}>๊ธ์์ </button>
</div>
);
}
โ state๋ฅผ ์์ ์ปดํฌ๋ํธ์ ๋ง๋ค์ด๋๋์ง๋ง modalTitle์ด๋ผ๋ state๋ App์๋ ์ฐ๊ณ Modal์๋ ์ฐ๊ธฐ๋๋ฌธ์ ๋ค์ํ ์ปดํฌ๋ํธ์์ ์ฐ์ด๋ state๋ ๋ถ๋ชจ์ปดํฌ๋ํธ์ ๋ง๋ค์ด์ผ ๋ถ๋ชจโ์์ ์ ์ก์ด ๊ฐ๋ฅํ๊ธฐ๋๋ฌธ์ ์ฌ์ฉํ๊ธฐ ์ฌ์
โ ์ฆ state๋ state๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ ์ค ์ ์ผ ์์์ ์๋ ๋ถ๋ชจ์ปดํฌ๋ํธ์ ๋ง๋ค์ด์ผํจ
<input>
์ ์ ๋ ฅ ์ ํน์ ์ฝ๋๋ฅผ ์คํํ๋ ค๋ฉด
onChange ์๋๋ฉด onInput ์ด๋ฒคํธํธ๋ค๋ฌ๋ฅผ ๋ถ์ฐฉํ๋ฉด ๋จ(์ ์ ๊ฐ ์ ๋ ฅํ ๋๋ง๋ค ์์ ์๋ ์ฝ๋ ์คํ)
์ด๋ฒคํธํธ๋ค๋ฌ๋ ์ข ๋ฅ๊ฐ ๋ง์ผ๋ ํ์ํ ๋๋ง๋ค ๊ฒ์ํด์ ์ฌ์ฉ
<input onChange={()=>{ ์คํํ ์ฝ๋ }}/>
<input>
์ ์ ๋ ฅํ ๊ฐ ๊ฐ์ ธ์ค๋ ๋ฒ
<input onChange={(e)=>{ console.log(e.target.value) }}/>
e๋ผ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ๊ณ e.target.value
e.target ์ด๋ฌ๋ฉด ํ์ฌ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๊ณณ์ ์๋ ค์ฃผ๊ณ
e.preventDefault() ์ด๋ฌ๋ฉด ์ด๋ฒคํธ ๊ธฐ๋ณธ ๋์์ ๋ง์์ฃผ๊ณ
e.stopPropagation() ์ด๋ฌ๋ฉด ์ด๋ฒคํธ ๋ฒ๋ธ๋ง๋ ๋ง์์ค๋๋ค. ์ด๊ฑฐ ์ฐ๋ฉด ์ข์์๋ฒํผ ๋๋ฅผ ๋ ๋ชจ๋ฌ์ฐฝ๋ ๋ ๋ฒ๋ฆฌ๋ ๋ฒ๊ทธ ํด๊ฒฐ๊ฐ๋ฅ
์ฌ์ฉ์๊ฐ input์ ์ ๋ ฅํ ๋ฐ์ดํฐ ์ ์ฅํ๊ธฐ
์ฌ์ฉ์๊ฐ input์ ์ ๋ ฅํ ๋ฐ์ดํฐ๋ state์๋๋ฉด ๋ณ์์ ์ ์ฅํด์ ์ฐ๋๊ฒ ์ผ๋ฐ์
function App (){
let [inputData, setInputData] = useState('');
return (
<input onChange={(e)=>{
setInputData(e.target.value)
console.log(inputData)
}} />
)
}
์ฐธ๊ณ ์ฌํญ
์์ ์ฝ๋ ์คํ์ ์ฒ์ ํ๋ฌธ์๋ฅผ ์ ๋ ฅํ๋ฉด ์ฝ์์ฐฝ์ ์๋ฌด๊ฒ๋ ์๋ฌ์ํ๋ก ์ถ๋ ฅ๋จ
์ด์ ๋ state๋ณ๊ฒฝํจ์์ ํน์ง๋๋ฌธ
๐ state๋ณ๊ฒฝํจ์๋ ์ฝ๊ฐ ๋ฆ๊ฒ ์ฒ๋ฆฌ๋จ (๋น๋๊ธฐ์ ์ฒ๋ฆฌ)
๊ทธ๋ฆฌ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๋ฆ๊ฒ ์ฒ๋ฆฌ๋๋ ์ฝ๋๋ค์ ์ ์ ์ ์ณ๋๊ณ ๋ฐ๋ก ๋ค์์ค์ ์คํํด์ค
์๋ React ๋ฌธ๋ฒ - class๋ฌธ๋ฒ์ผ๋ก ์ปดํฌ๋ํธ
class Modal2 extends React.Component {
constructor(props){ //๋ถ๋ชจ๊ฐ ๋ณด๋ธ props
super(props);
this.state = { //state๋ฌธ๋ฒ - object๋ฌธ๋ฒ๊ณผ ๋์ผ
name : 'kim',
age : 20
}
}
render(){
return (
<div>์๋
{ this.props.ํ๋กญ์ค์ด๋ฆ }</div> //๋ถ๋ชจ๊ฐ ๋ณด๋ธ props์ถ๋ ฅ
<button onClick={()=>{ this.setState({age : 21}) }}>๋ฒํผ</button> )
} //state๋ณ๊ฒฝํจ์
}
react์์ ๋ถํธ์คํธ๋ฉ ์ฌ์ฉ
๊ตฌ๊ธ์์ react bootstrap ๊ฒ์ํ๋ฉด ๋์ค๋ ์ฌ์ดํธ์์ ์ฌ์ดํธ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์คํ์ค์ด๋ฉด ๋๊ณ npm install์ ํ์๋๊ฑฐ ๋ณต๋ถ โ ํน์ ์คํ์ผ์ bootstrap cssํ์ผ์ ํ์๋กํ๊ธฐ๋๋ฌธ์ ๋ณต๋ถ
๋๋ฌธ์๋ก ์์ํ๋ ๊ฒ๋ค์ ์ปดํฌ๋ํธ์ด๊ธฐ ๋๋ฌธ์ ์ปดํฌ๋ํธ๋ค์ ์ ๋ถ import ํด์ค์ผํจ
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Navbar, Container, Nav} from 'react-bootstrap';
function App() {
return (
<div className="App">
<Navbar bg="dark" variant="dark">
<Container>
<Navbar.Brand href="#home">Navbar</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#features">Features</Nav.Link>
<Nav.Link href="#pricing">Pricing</Nav.Link>
</Nav>
</Container>
</Navbar>
</div>
);
}
export default App;
์ด๋ฏธ์ง ๋ฃ๋ ๋ฒ
cssํ์ผ์์ srcํด๋์์ ์๋ ์ฌ์ง์ ์ฌ์ฉํ๋ ค๋ฉด /์ด๋ฏธ์ง๊ฒฝ๋ก ์ฌ์ฉ
background-image : url('./bg.png');
html์์์ srcํด๋์ ์ด๋ฏธ์ง๋ฅผ ๋ฃ์๋ ค๋ฉด ์ด๋ฏธ์ง๋ฅผ importํด์ค๊ณ ์ฌ์ฉ
<img>
ํ๊ทธ ์ฐ๊ณ ์ถ์ผ๋ฉด <img src={bg}/>
์ด๋ ๊ฒ ์จ๋ ๋ณด์
๋๋ค.
๊ท์ฐฎ์ผ๋ฉด cssํ์ผ์ ํ์ฉํฉ์๋ค.
import bg from './bg.png'
function App(){
return (
<div>
<div className="main-bg" style={{ backgroundImage : 'url(' + bg + ')' }}></div>
</div>
)
}
์ด๋๊ฐ์ ํธ์คํ ๋์ด์๋ ์ธ๋ถ ์ด๋ฏธ์ง๋ ์ ๋๊ฒฝ๋ก ๊ทธ๋๋ก ์์ฑํ๋ฉด ์๋ณด์
<img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%"></img>
๐ํ๋ฉด์ ๊ฐ๋ก๋ก 3๋ฑ๋ถ
์ค์ React-bootstrap ์ฌ์ดํธ์์ Row ์๋๋ฉด Grid ๋ผ๊ณ ๊ฒ์
public ํด๋์ ์ฉ๋
์ฌ๋ฌ๊ฐ์ง ์์ค์ฝ๋๋ srcํด๋์ ๋ณด๊ด / ์ด๋ฏธ์ง๊ฐ์ staticํ์ผ์ ๊ฒฝ์ฐ publicํด๋์ ๋ณด๊ดํด๋๋จ
๋ฆฌ์กํธ๋ก ๊ฐ๋ฐ์ ์๋ฃํ๋ฉด build์์ ์ ํ๋๋ฐ ์ง๊ธ๊น์ง ์งฐ๋ ์ฝ๋๋ฅผ ํ ํ์ผ๋ก ์์ถํ๋ ์์
srcํด๋์ ์๋ ์ฝ๋์ ํ์ผ์ ๋ค ์์ถ์ด ๋๋๋ฐ publicํด๋์ ์๋ ๊ฒ๋ค์ ๊ทธ๋๋ก ๋ณด์กดํด์ค
ํํ๋ฅผ ๋ณด์กดํ๊ณ ์ถ์ ์ด๋ฏธ์ง,txt,json๋ฑ ์์ ์ด ํ์์๋ staticํ์ผ๋ค์ ๊ฒฝ์ฐ์ publicํด๋์ ๋ณด๊ดํด๋ ์๊ด์์
publicํด๋์ ์๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ๋
<img src="/logo192.png" />
๊ทธ๋ฅ /์ด๋ฏธ์ง๊ฒฝ๋ก ์ฌ์ฉํ๋ฉด ๋จ โ publicํด๋์ ์๋ ์ด๋ฏธ์ง ์ฌ์ฉํ ๋๋ import๋ฅผ ์ํด๋๋จ , cssํ์ผ์์๋ /์ด๋ฏธ์ง๊ฒฝ๋ก ์ฌ์ฉํ๋ฉด๋จ
๊ถ์ฅ๋๋ ๋ฐฉ์
<img src={process.env.PUBLIC_URL + '/logo192.png'} />
๋ฆฌ์กํธ๋ก ๋ง๋ htmlํ์ด์ง๋ฅผ ๋ฐฐํฌํ ๋ codingapple.com๊ฒฝ๋ก์ ๋ฐฐํฌํ๋ฉด ๋ฌธ์ ๊ฐ ์์ง๋ง
condingapple.com/์ด์ฉ๊ตฌ/ ๊ฒฝ๋ก์ ๋ฐฐํฌํ๋ฉด
/logo192.png ์ด๋ ๊ฒ ์ฐ๋ฉด ํ์ผ์ ์ฐพ์ ์ ์๋ค๊ณ ๋์ฌ ์๋ ์์
๊ทธ๋์ /์ด์ฉ๊ตฌ/ ๋ฅผ ๋ปํ๋ process.env.PUBLIC_URL ์ด๊ฒ๋ ๋ํด์ฃผ๋ฉด ๋จ
codingapple.com/์ด์ฉ๊ตฌ/ ๊ฒฝ๋ก์ ๋ฆฌ์กํธ๋ก ๋ง๋ ํ์ด์ง๋ฅผ ๋ฐฐํฌํ ์ผ์ด ์์ ์์ผ๋ฉด ๊ตณ์ด ์ํด๋ ๋จ
์๋ฒ๊ฐ ์์ด์ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ง ๋ชปํ๋ jsํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ ๋ฐ์์ค๋๊ฒ์ฒ๋ผ ๋ง๋ค๊ธฐ
export default / import ๋ฌธ๋ฒ
์๋ฅผ๋ค์ด ์ํ์ ๋ณด๋ค์ state๋ก ๋ง๋ค๊ณ ์ถ์๋ฐ useState()์์ ๋ฃ๊ธฐ์ ๋๋ฌด ๊ธธ๋
๋ค๋ฅธํ์ผ์ ๋ณด๊ดํ๋ค๊ฐ importํด์ฌ ์ ์์
(์ ์์ )
(data.js ํ์ผ)
let a = 10;
export default a; //export default ๋ณ์๋ช
; ์ํ๋ ๋ณ์๋ฅผ ๋ด๋ณด๋
(App.js ํ์ผ)
import a from './data.js'; //๊ฐ์ ธ์ฌํ์ผ import
console.log(a)
/////////////////์ฌ๋ฌ๊ฐ์ ๋ณ์๋ค์ ๋ด๋ณด๋ผ๋/////////////////
(data.js ํ์ผ)
var name1 = 'Kim';
var name2 = 'Park';
export { name1, name2 } //์ฌ๋ฌ๊ฐ ๋ณด๋ผ๋ ์ฌ์ฉ
(App.js ํ์ผ)
import { name1, name2 } from './data.js';
<div className="container">
<div className="row">
{shoes.map(function(a, i){
return(
<Card shoes={shoes} i={i} key={i}></Card>
)
})}
</div>
</div>
</div>
);
}
function Card(props){
return(
<div className="col-md-4">
//์๋ฐ์คํฌ๋ฆฝํธ ์
๋ ฅ์์ํด {}๋ฅผ ๋ถ์ด๊ณ '๋ฌธ์'+ ๋ณ์ +'๋ฌธ์ ํํ๋ก ๋ฌธ์์ค๊ฐ์ ๋ณ์๋ฃ๊ธฐ๊ฐ๋ฅ
<img src={'https://codingapple1.github.io/shop/shoes'+ (props.i+1) +'.jpg'} width="80%"></img>
<h4>{props.shoes[props.i].title}</h4>
<p>{props.shoes[props.i].price}</p>
</div>
)
}
ํ์ด์ง ๋๋๊ธฐ
์ผ๋ฐ html css js์ฌ์ดํธ๋ ๊ทธ๋ฅ htmlํ์ผ ์ฌ๋ฌ๊ฐ๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ์ง๋ง
๋ฆฌ์กํธ๋ ํ๋์ htmlํ์ผ๋ง ์ฌ์ฉ
โ ๋ฆฌ์กํธ์์ ๋ค๋ฅธ ํ์ด์ง๋ฅผ ์์ฒญํ๋ฉด ๊ทธ๋ฅ ๋ด๋ถ์ ์๋ <div>
๋ฅผ ๊ฐ์์น์์ ๋ณด์ฌ์ค
react-router-dom์ด๋ผ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ ๊ตฌํํ๋๊ฒ ์ผ๋ฐ์
react-router-dom ์ค์น๋ฐฉ๋ฒ
react-router-dom ํํ์ด์ง๊ฐ์ ๋ฐ๋ผํ๋ฉด ๋จ
ํด๋น ํ์ผ ํฐ๋ฏธ๋์์ npm install react-router-dom@6 ์ ๋ ฅ(6๋ฒ์ )
์ธํ ๋ฐฉ๋ฒ
index.jsํ์ผ์์ <BrowserRouter>
์ด๊ฑธ๋ก <App/>
์ ๊ฐ์ธ๋ฉด ๋ (import๋ ์๋์ผ๋ก ๋จ / ์๋๋ฉด importํด์ผ)
๋ผ์ฐํฐ๋ก ํ์ด์ง ๋๋๋ ๋ฐฉ๋ฒ
element์์ html์์ฑํ ๋ ์ฝ๋๊ฐ ๊ธธ๋ฉด ์ปดํฌ๋ํธ๋ก ๋ง๋ค๊ฑฐ๋ ๋ค๋ฅธ ํ์ผ์ ์์ฑ ํ importํ์ฌ ์ฌ์ฉ=>๋ณดํต ์ด๋ ๊ฒ ์ฌ์ฉ
import { Routes, Route, Link } from 'react-router-dom'
function App(){
return (
(์๋ต)
<Routes>
<Route path="/" element={ <div>๋ฉ์ธํ์ด์ง์์ ๋ณด์ฌ์ค๊ฑฐ</div> } />
<Route path="/detail" element={ <div>์์ธํ์ด์ง์</div> } />
<Route path="/about" element={ <div>์ด๋ฐ์ํ์ด์ง์</div> } />
</Routes>
)
}
ํ์ด์ง์ด๋ ๋ฒํผ
๋งํฌ๋ฅผ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด react-router-dom์์ Link ์ปดํฌ๋ํธ import ํด์ค๊ณ
์ํ๋ ๊ณณ์์ ์ฐ๋ฉด ๋ฉ๋๋ค.
<Link to="/">ํ</Link>
<Link to="/detail">์์ธํ์ด์ง</Link>
๋ฆฌ์กํธ ํ๋ก์ ํธ ํด๋๊ตฌ์กฐ
๋ฆฌ์กํธ๋ ๊ทธ๋ฅ html ์ด์๊ฒ ๋ง๋ค์ด์ฃผ๋ ์ชผ๊ทธ๋งํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ผ ๋ฟ์ ๋๋ค.
๊ทธ๋์ ์ฌ๋ฌ๋ถ์ด ๋ง๋ค ํ์ผ๋ค์ 95% ํ๋ฅ ๋ก .js ํ์ผ์ด๊ธฐ ๋๋ฌธ์
๋น์ทํ .js ํ์ผ๋ผ๋ฆฌ ํ ํด๋์ ๋ฌถ์ด๋์ผ๋ฉด ๊ทธ๋ฅ ๊ทธ๊ฒ ์ข์ ํด๋๊ตฌ์กฐ์ ๋๋ค.
์ปดํฌ๋ํธ ์ญํ ํ๋ js ํ์ผ์ components ํด๋์ ๋ฌถ๊ณ
ํ์ด์ง ์ญํ ํ๋ js ํ์ผ์ routes ์๋๋ฉด pages ํด๋์ ๋ฌถ๊ณ
์์ฃผ ์ฐ๋ ํจ์๊ฐ ๋ค์ด์๋ js ํ์ผ์ utils ํด๋์ ๋ฌถ๊ณ
useNavigate , Outlet
์๋จ์ import
import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom'
ํ์ด์ง ์ด๋๊ธฐ๋ฅ์ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด useNavigate()์ฌ์ฉ
useNavigate vs Link
https://velog.io/@seokkitdo/React-Link-useNavigate
Link์จ๋ ๊ฐ๋ฅ
function App(){
let navigate = useNavigate()
return (
(์๋ต)
<button onClick={()=>{ navigate('/detail') }}>์ด๋๋ฒํผ</button>
)
}
useNavigate() ์ฐ๋ฉด ๊ทธ ์๋ฆฌ์ ์ ์ฉํ ํจ์๊ฐ ๋จ์ - ํ์ด์ง๋ฅผ ์ด๋์์ผ์ฃผ๋ ํจ์
navigate(-1) : ๋ค๋ก1๋ฒ๊ฐ๊ธฐ navigate(2) : ์์ผ๋ก 2๋ฒ๊ฐ๊ธฐ
404ํ์ด์ง
์ ์ ๊ฐ ์ด์ํ๊ฒฝ๋ก๋ก ์ ์ํ์ ๋ โ์๋ํ์ด์งโ ์์ ์๋ ค์ฃผ๊ณ ์ถ์๋
<Route path="*" element={ <div>์๋ํ์ด์ง์</div> } />
<Route path="*">
ํ๋ ๋งจ ๋ฐ์ ๋ง๋ค์ด๋๋ฉด ๋ฉ๋๋ค.
*
์ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๋ปํด์ ๋ง๋ค์ด๋ ๊ฒฝ๋ก๊ฐ ์๋ ๋ค๋ฅธ ํ์ด์ง๋ก ์ ์์ *๊ฒฝ๋ก๋ก ์๋ดํจ
์๋ธ๊ฒฝ๋ก ๋ง๋ค ์ ์๋ Nested routes
<Route>
์์ <Route>
๋ฅผ ๋ฃ๋๊ฒ์ Nested routes
<Route path="/about" element={ <About/> } >
<Route path="member" element={ <div>๋ฉค๋ฒ๋ค</div> } /> {/* /about/member */}
<Route path="location" element={ <div>ํ์ฌ์์น</div> } /> {/* /about/location */}
</Route>
function About(){
return (
<div>
<h4>aboutํ์ด์ง์</h4>
<Outlet></Outlet>
</div>
)
}
/about/member โ Aboutํ์ด์ง์ <Outlet>
์๋ฆฌ์ <div>๋ฉค๋ฒ๋ค</div>
๋ณด์ฌ์ค
/about/location โ Aboutํ์ด์ง์ <Outlet>
์๋ฆฌ์ <div>ํ์ฌ์์น<div>
๋ณด์ฌ์ค
import ํด์จ <Outlet>
์ nested routes ์์ element๋ค์ ์ด๋์ ๋ณด์ฌ์ค์ง ํ๊ธฐํ๋ ๊ณณ
ํ์ด์ง url์ ๋ฐ๊ฟ๋๋ง๋ค ๊ฐ๊ฐ ๋ค๋ฅธ ui๋ฅผ ๋ณด์ฌ์ฃผ๋๋ฐ ์ด๊ฒ๋ ๋์ ์ด ui๋ง๋๋ ๋ฐฉ๋ฒ ์ค ํ๋
์ฅ์ : ๋ผ์ฐํฐ๋ฅผ ์ฐ๋ฉด ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ์ด ์ด์ฉ๊ฐ๋ฅํ๋ค
์๋ฃ์ ์์ ๋ณ๊ฒฝ ์ ์์ธํ์ด์ง๋ ๊ณ ์ฅ๋๋ ๋ฌธ์ ํด๊ฒฐ๋ฐฉ๋ฒ
์ํ์์๋ฅผ ๊ฐ๋๋ค์์ผ๋ก ์ ๋ ฌํ๋ ๋ฒํผ์ ๋๋ฅด๋ฉด
shoes์ state์์ ์ํ์ด ๊ฐ๋๋ค์์ผ๋ก ์ ๋ ฌ๋๋ค๊ณ ๊ฐ์
๋ฒํผ์ ๋๋ฅด๊ธฐ ์ ์ /detail/0ํ๋ฉด White and Black๊ฐ ๋ณด์ฌ์ง๋๋ฐ ๋ฒํผ์ ๋๋ฅธ ํ์ /detail/0ํ๋ฉด Grey Yordan์ด ๋ณด์ฌ์ง
โ ์์ธํ์ด์ง๊ฐ ๋ถ๊ท์นํด์ง
detailPage.js์์ ๋ฐ์ดํฐ๋ฐ์ธ๋ฉ ์ ์ ๋ ฅํ ๊ฐ๋ฒ์งธ์ ์ํ์ ๋ณด์ฌ์ฃผ๋ ๊ฑธ๋ก ์ฝ๋๋ฅผ ์งฌ
โ ํด๋น ์ฝ๋๋ฅผ ์ํ์ id๊ฐ ์ ๋ ฅํ๊ฐ์ธ ์ํ์ ๋ณด์ฌ์ฃผ๋๊ฑธ๋ก ์ฝ๋๋ฅผ ๋ณ๊ฒฝ
ํ์ฌ url์ ์ ๋ ฅํ ๋ฒํธ์ ๊ฐ์ ๋ฒํธ๋ฅผ ๊ฐ์ง ์ํ์ ์ฐพ์์ ๋ฐ์ดํฐ๋ฐ์ธ๋ฉ
.find() , .filter() ๋ฌธ๋ฒ ์ฌ์ฉ
import { useParams } from 'react-router-dom';
function DetailPage(props){
let {id} = useParams(); //typeofํด๋ณด๋ฉด string์ผ๋ก ๋์ด
//arrow function์์ return๊ณผ ์ค๊ดํธ๋ ๋์์ ์๋ต๊ฐ๋ฅ
//let findItem = props.shoes.find((x) => x.id == id ) ์ด๋ ๊ฒ ์จ๋ ๊ฐ์
let findItem = props.shoes.find(function(x){ //find()์ฝ๋ฐฑํจ์์๋ฆฌ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ์ผ๋ฉด array์ ์๋ฃ๋ฅผ ๋ป
return x.id == id //array์๋ฃ.id == url์ ์
๋ ฅํ ๋ฒํธ
})
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<img src={'https://codingapple1.github.io/shop/shoes'+ (findItem.id+1) + '.jpg'} width="100%" ></img>
</div>
<div className="col-md-6">
<h4 className="pt-5">{findItem.title}</h4>
<p>{findItem.content}</p>
<p>{findItem.price}</p>
<button className="btn btn-danger">์ฃผ๋ฌธํ๊ธฐ</button>
</div>
</div>
</div>
);
}
export default DetailPage;
styled-component
์ค์น (npm install styled-components)
์คํ์ผ์ ๋ฐ๋ก ์ ํ์ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
import styled from 'styled-components'
์ฅ์ 1.ย CSS ํ์ผ ์คํํ ํ์์์ด JS ํ์ผ์์ ๋ฐ๋ก ์คํ์ผ๋ฃ์ ์ ์์
์ฅ์ 2.ย ์ฌ๊ธฐ ์ ์ ์คํ์ผ์ด ๋ค๋ฅธ JS ํ์ผ๋ก ์ค์ผ๋์ง ์์ต๋๋ค. ์๋ ๊ทธ๋ฅ CSSํ์ผ์ ์ค์ผ๋ฉ๋๋ค.
์ฅ์ 3.ย ํ์ด์ง ๋ก๋ฉ์๊ฐ ๋จ์ถ๋ฉ๋๋ค.
์๋๋ฉด ์ ๊ธฐ ์ ์ ์คํ์ผ์ html ํ์ด์ง์ <style>
ํ๊ทธ์ ๋ฃ์ด์ค์ ๊ทธ๋ ์ต๋๋ค.
์ผ๋ฐ cssํ์ผ ์ค์ผ๋ฐฉ์ง ๋ฐฉ๋ฒ
์ฌ๋ฌ๋ถ์ด App.css ํ์ผ์ ๋ง๋ค์ด์ App.js์์ importํด์ ์ด๋ค๊ณ ํด๋
๊ฑฐ๊ธฐ ์ ์ ํด๋์ค๋ช ๋ค์ Detail.js๊น์ง ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค. (์ค์ผ๋จ)
ํ๋ก์ ํธ ์ฌ์ด์ฆ๊ฐ ์์ ๋ ํธ๋ฆฌํ๊ฒ ์ง๋ง ์ฌ์ด์ฆ๊ฐ ์ปค์ง๋ฉด ๊ด๋ฆฌํ๊ธฐ ํ๋ค์ด์ง๋๋ค.
๊ทธ๋ด ๋ styled-components ์จ๋ ๋์ง๋ง ๊ทธ๋ฅ CSSํ์ผ์์๋ ๋ค๋ฅธ JS ํ์ผ์ ๊ฐ์ญํ์ง ์๋ '๋ชจ๋ํ' ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ
์ปดํฌ๋ํธ๋ช .module.css
์ด๋ ๊ฒ CSS ํ์ผ์ ์๋ช ํ๋ฉด ๋ฉ๋๋ค. ex) App.module.css / detailPage.module.css
๊ทธ๋ฆฌ๊ณ ์ปดํฌ๋ํธ๋ช .js ํ์ผ์์ import ํด์ ์ฐ๋ฉด ๊ทธ ์คํ์ผ๋ค์ ์ปดํฌ๋ํธ๋ช .js ํ์ผ์๋ง ์ ์ฉ๋ฉ๋๋ค.
let Box = styled.div`
padding : 20px;
color : grey
`;
let YellowBtn = styled.button`
background : yellow;
color : black;
padding : 10px;
`;
function Detail(){
return (
<div>
<Box>
<YellowBtn>๋ฒํผ์</YellowBtn>
</Box>
</div>
)
}
import styled from 'styled-components';
let YellowBtn = styled.button`
background : ${ props => props.bg }; //bg ์๋ฆฌ์ ์์ ๋กญ๊ฒ ์๋ช
๊ฐ๋ฅ
color : ${ props => props.bg == 'blue' ? 'white' : 'black' };
//bg๊ฐ blue๋ฉด ๊ธ์์์ white๋ก ์๋๋ฉด black์ผ๋ก ์ผํญ์ฐ์ฐ์ ์ฌ์ฉ
padding : 10px;
`;
function Detail(){
return (
<div>
<YellowBtn bg="orange">์ค๋ ์ง์ ๋ฒํผ์</YellowBtn>
<YellowBtn bg="blue">ํ๋์ ๋ฒํผ์</YellowBtn>
</div>
)
}
๋จ์ 1.ย JS ํ์ผ์ด ๋งค์ฐ ๋ณต์กํด์ง
๊ทธ๋ฆฌ๊ณ ์ด ์ปดํฌ๋ํธ๊ฐ styled ์ธ์ง ์๋๋ฉด ์ผ๋ฐ ์ปดํฌ๋ํธ์ธ์ง ๊ตฌ๋ถ๋ ์ด๋ ค์์ง
๋จ์ 2.ย JS ํ์ผ ๊ฐ ์ค๋ณต ๋์์ธ์ด ๋ง์ด ํ์ํ๋ฉด ๋ค๋ฅธ ํ์ผ์์ ์คํ์ผ ๋ฃ์ ๊ฒ๋ค import ํด์์ ์ฌ์ฉ
๊ทผ๋ฐ ๊ทธ๋ผ CSSํ์ผ ์ฐ๋๊ฑฐ๋ ์ฐจ์ด๊ฐ ์์ด์ง
๋จ์ 3.ย CSS ๋ด๋นํ๋ ๋์์ด๋๊ฐ ์๋ค๋ฉด ํ์ ์ ๋ถํธํ ํ ๋ฐ ๊ทธ ์ฌ๋์ด styled-components ๋ฌธ๋ฒ์ ๋ชจ๋ฅธ๋ค๋ฉด
๊ทธ ์ฌ๋์ด CSS๋ก ์ง ๊ฑธ styled-components ๋ฌธ๋ฒ์ผ๋ก ๋ค์ ๋ฐ๊พธ๊ฑฐ๋ ๊ทธ๋ฐ ์์ ์ด ํ์ํด์ง
ํ๊ฒฝ์ ๋ฐ๋ผ ์์๊ฐํด๋ณด๊ณ ์ฌ์ฉํด์ผํจ
๐ ์ปดํฌ๋ํธ์ Lifecycle
์ปดํฌ๋ํธ์ lifecycle ์ค๊ฐ์ค๊ฐ์ ๊ฐ์ญ(์ฝ๋์คํ)์ด ๊ฐ๋ฅ โ ๋ค์ํ ๊ธฐ๋ฅ ๊ธฐ๋ฐ์ด ๊ฐ๋ฅ
์ปดํฌ๋ํธ Lifecycle์ ๊ฐ์ญ(์ฝ๋์คํ)ํ๋ ๋ฐฉ๋ฒ
๊ฐ๊ณ ๋ฆฌ๋ฅผ ๋ฌ์์ ์ฝ๋๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋จ
hook(๊ฐ๊ณ ๋ฆฌ) ์ ๋ฌ์์ค โ Lifecycle hook์ด๋ผ๊ณ ๋ถ๋ฆ
์์ฆ React์์ Lifecycle hook ์ฐ๋ ๋ฐฉ๋ฒ
import {useState, useEffect} from 'react'; //useEffect importํด์ผํจ
function Detail(){
useEffect(()=>{
//์ฌ๊ธฐ์ ์ ์ฝ๋๋ ์ปดํฌ๋ํธ ๋ก๋ & ์
๋ฐ์ดํธ ๋ง๋ค ์คํ๋จ
console.log('์๋
')
});
let [count, setCount] = useState(0)
return (
<button onClick={()=>{ setCount(count+1) }}>๋ฒํผ</button>
)
}
useEffect์ ์ฝ๋ฐฑํจ์๋ฅผ ์ถ๊ฐํด์ ์์ ์ฝ๋๋ฅผ ์ ์ผ๋ฉด ํด๋น ์ฝ๋๋ ์ปดํฌ๋ํธ๊ฐ mount & update ์ ์คํ๋จ
โ์๋ โ์ด 2๋ฒ ์ถ๋ ฅ
โ index.js์ <React.StrictMode>๋ผ๋ ํ๊ทธ๊ฐ ์์ผ๋ฉด 2๋ฒ ์ถ๋ ฅํด์ค
๋๋ฒ๊น ์ฉ์ผ๋ก ํธํ๋ผ๊ณ 2๋ฒ ์ถ๋ ฅํด์ฃผ๋๋ฐ ์ซ์ผ๋ฉด ์ ํ๊ทธ๋ฅผ ์ ๊ฑฐ
useEffect๋ฐ์ ์ ์ด๋ ๋๊ฐ์ด ๋์?
useEffect ๋ฐ์ ์ ์ด๋ ๋๊ฐ์ด ์ปดํฌ๋ํธ mount & update ์ ์คํ๋จ
-์ปดํฌ๋ํธ๊ฐ mount & update ์ function ์์ ์๋ ์ฝ๋๋ ๋ค์ ์ฝ๊ณ ์ง๋๊ฐ๊ธฐ ๋๋ฌธ
โuseEffect ์์ ์ ์ ์ฝ๋๋ html ๋๋๋ง ์ดํ์ ๋์ํจ
์๋ฅผ ๋ค์ด ์๊ฐ์ด ์ค๋๊ฑธ๋ฆฌ๋ ์ฝ๋๊ฐ ํ์ํ๋ค๊ณ ๊ฐ์
function Detail(){
(๋ฐ๋ณต๋ฌธ 10์ต๋ฒ ๋๋ฆฌ๋ ์ฝ๋)
return (์๋ต)
}
-์ฌ๊ธฐ์ html์ ์ผ๋ฉด ๋ฐ๋ณต๋ฌธ๋๋ฆฌ๊ณ ๋์ html์ ๋ณด์ฌ์ค
function Detail(){
useEffect(()=>{
(๋ฐ๋ณต๋ฌธ 10์ต๋ฒ ๋๋ฆฌ๋ ์ฝ๋)
});
return (์๋ต)
}
-useEffect์์ ์ ์ผ๋ฉด html ๋ณด์ฌ์ฃผ๊ณ ๋์ ๋ฐ๋ณต๋ฌธ ์คํ
โuseEffect๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์คํ์์ ์ ์กฐ์ ํ ์ ์์
ํจ์๋ฅผ useEffect๋ผ๊ณ ์๋ช ํ ์ด์ - ํจ์์ ํต์ฌ๊ธฐ๋ฅ ์ธ์ ์ธ๋ฐ์๋ ๊ธฐ๋ฅ๋ค์ ํ๋ก๊ทธ๋๋ฐ ์ฉ์ด๋ก side effect
์ปดํฌ๋ํธ์ ํต์ฌ๊ธฐ๋ฅ์ html ๋ ๋๋ง์ด๋ผ side effect์์ ์ด๋ฆ์ ๋ฐ์ด
html ๋ ๋๋ง ์ธ์ ์ธ๋ฐ์๋ ๊ธฐ๋ฅ๋ค์ useEffect์์ ์ ๊ธฐ
์ค๋๊ฑธ๋ฆฌ๋ ๋ฐ๋ณต์ฐ์ฐ, ์๋ฒ์์ ๋ฐ์ดํฐ๊ฐ์ ธ์ค๋ ์์ , ํ์ด๋จธ๋ค๋๊ฒ๋ค์ useEffect ์์ ๋ง์ด ์ ์
๐ ๋ฆฌ์กํธ์์ ๋์ ์ธ UI ๋ง๋ค๊ธฐ
function Detail(){
let [alert, setAlert] = useState(true) //UI์ํ๋ฅผ ์ ์ฅํ state
useEffect(()=>{
setTimeout(()=>{ setAlert(false) }, 2000) //2์ด ํ alert๋ฅผ false
}, []) //[]๋ ์คํ์กฐ๊ฑด - ์๋ฌด๊ฒ๋ ์๋ค์ด๊ฐ์๊ธฐ ๋๋ฌธ์ mount์ 1ํ๋ง ์คํ
return (
{
//์ผํญ์ฐ์ฐ์ ์ฌ์ฉ
alert == true
? <div className="alert alert-warning">
2์ด์ด๋ด ๊ตฌ๋งค์ ํ ์ธ
</div>
: null
}
)
}
useEffect์ ๋ฃ์ ์ ์๋ ์คํ์กฐ๊ฑด
useEffect(()=>{ ์คํํ ์ฝ๋ }, [count]) //count๊ฐ ๋ณํ ๋๋ง ์ฝ๋ ์คํ
useEffect(()=>{ ์คํํ ์ฝ๋ }, [])
useEffect์ ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก []๋ฅผ ๋ฃ์ ์ ์๋๋ฐ ์ฌ๊ธฐ์ ๋ณ์๋ state๊ฐ์ ๊ฒ๋ค์ ๋ฃ์ ์ ์์(์ฌ๋ฌ๊ฐ ๊ฐ๋ฅ)
โ []์์ ๋ฃ์ผ๋ฉด []์ ์๋ ๋ณ์๋ state๊ฐ ๋ณํ ๋๋ง useEffect์์ ์ฝ๋๋ฅผ ์คํ
[]์์ ์๋ฌด๊ฒ๋ ์๋ฃ์ผ๋ฉด ์ปดํฌ๋ํธ mount์(๋ก๋์) 1ํ๋ง ์คํํ๊ณ ๋์ด์ ์คํํ์ง์์
clean up function
useEffect๋์ํ๊ธฐ ์ ์ ํน์ ์ฝ๋๋ฅผ ์คํํ๊ณ ์ถ์ผ๋ฉด return ()โ{}์์ ๋ฃ์ผ๋ฉด ๋จ
return ์์ ์๋ ์ฝ๋๋ฅผ ๋จผ์ ์คํ
useEffect(()=>{
๊ทธ ๋ค์ ์คํ๋จ
return ()=>{
์ฌ๊ธฐ์๋๊ฒ ๋จผ์ ์คํ๋จ
}
}, [count])
์๋ฅผ ๋ค๋ฉด ์์ ๋ก ํ๋ setTimeout ํ์ด๋จธ์ธ๋ฐ
setTimeout() ์ธ ๋๋ง๋ค ๋ธ๋ผ์ฐ์ ์์ ํ์ด๋จธ๊ฐ ํ๋ ์๊น
๊ทผ๋ฐ useEffect ์์ ์ผ๊ธฐ ๋๋ฌธ์ ์ปดํฌ๋ํธ๊ฐ mount ๋ ๋ ๋ง๋ค ์คํ
๊ทธ๋ผ ์๋ชป ์ฝ๋๋ฅผ ์ง๋ฉด ํ์ด๋จธ๊ฐ 100๊ฐ 1000๊ฐ ์๊ธธ ์๋ ์์
๋์ค์ ๊ทธ๋ฐ ๋ฒ๊ทธ๋ฅผ ๋ฐฉ์งํ๊ณ ์ถ์ผ๋ฉดuseEffect์์ ํ์ด๋จธ ๋ง๋ค๊ธฐ ์ ์ ๊ธฐ์กด ํ์ด๋จธ๋ฅผ ์น ์ ๊ฑฐํ๋ผ๊ณ ์ฝ๋๋ฅผ ์ง๋ฉด ๋๋๋ฐ
๊ทธ๋ฐ๊ฑฐ ์งค ๋ return ()=>{} ์์ ์ง๋ฉด ๋จ
useEffect(()=>{
let a = setTimeout(()=>{ setAlert(false) }, 2000) //์ ๊ฑฐํ๊ธฐ์ํด์ ๋ณ์์ ๋ฃ๊ณ
return ()=>{
clearTimeout(a) //ํ์ด๋จธ๋ฅผ ์ ๊ฑฐํ๋ ํจ์
}
}, [])
๐ ์ ๋ฆฌ
useEffect( ()=>{ ์คํํ ์ฝ๋ } ) // ์ฌ๋๋๋ง๋ง๋ค ์ฝ๋ ์คํ๊ฐ๋ฅ
useEffect( ()=>{ ์คํํ ์ฝ๋ }, [] ) //์ปดํฌ๋ํธ mount์ 1ํ๋ง ์คํ
useEffect( ()=>{ return ()=>{ ์คํํ ์ฝ๋ } } ) //useEffect์์ ์ฝ๋์คํ์ ์ ํญ์ ์คํ
useEffect( ()=>{ return ()=>{ ์คํํ ์ฝ๋ } }, [] ) //์ปดํฌ๋ํธ unmount์ 1ํ ์คํ
useEffect( ()=>{ ์คํํ ์ฝ๋ }, [state1] ) //state1์ด ๋ณ๊ฒฝ๋ ๋๋ง ์คํ
input์ ์ซ์๋ง๊ณ ๋ค๋ฅธ๊ฑธ ์ ๋ ฅํ๋ฉด alert์ฐฝ๋์ฐ๊ธฐ
input์ ์ ๋ ฅํ ๊ฐ์ ์ ๋ถ ๋ฌธ์ํํ๋ก ์ถ๋ ฅ โ โ123โ โใฑใดใทโ์ด๋ ๊ฒ ์ซ์๊ฐ ์๋ ๋ฌธ์์ธ์ง ํ์ ํ๊ณ ์ถ์ผ๋ฉด isNaN()์ฌ์ฉ
function Detail(){
let [num, setNum] = useState('')
useEffect(()=>{
if (isNaN(num) == true){ //๋ฌธ์๊ฐ ๋ค์ด์์ผ๋ฉด true๊ฐ ๋์ด
alert('๊ทธ๋ฌ์ง๋ง์ธ์')
}
}, [num])
return (
<input onChange((e)=>{ setNum(e.target.value) }) />
)
}
์๋ฒ ์์ฒญ
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ (GET) / ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ๋ณด๋ผ ๋ (POST)
GET / POST ์์ฒญํ๋ ๋ฒ
POST์์ฒญ์ ๋ ๋ฆฌ๊ณ ์ถ์ผ๋ฉด
<form action="์์ฒญํ url" method="post">
โ GET, POST ์์ฒญ์ ์ ๋ ๊ฒ ๋ ๋ฆฌ๋ฉด ๋จ์ : ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ก๊ณ ์นจ๋จ
AJAX๋?
์๋ฒ์ GET, POST์์ฒญํ ๋ ์๋ก๊ณ ์นจ ์์ด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ๋์์ฃผ๋ ๊ฐ๋จํ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ
AJAX๋ก GET/POST์์ฒญํ๋ ๋ฐฉ๋ฒ 3๊ฐ
โ npm install axios๋ก ์ค์น
AJAX ์์ฒญํ๋ ๋ฐฉ๋ฒ
import axios from 'axios'
function App(){
return (
<button onClick={()=>{
axios.get('https://codingapple1.github.io/shop/data2.json')
.then((result)=>{
//console.log(result.data) ์ฌ๊ธฐ์์ ๊ฒฐ๊ณผ๊ฐ ๋ค์ด์์
let newShoes = shoes.concat(result.data)
// let copy = [...shoes, ...result.data] ์ด๋ ๊ฒ๋ ๊ฐ๋ฅ
// console.log(copy)
setShoes(newShoes)
})
.catch(()=>{
console.log('์คํจ')
})
}}>์ํ ๋๋ณด๊ธฐ</button>
)
}
POST ์์ฒญํ๋๋ฒ
axios.post('URL', {name : 'kim'})
//url์๋ฒ๋ก ์๋ฃ์ ์ก / ์๋ฃ์ ํน์ ์ฝ๋๋ฅผ ์คํํ๊ณ ์ถ์ผ๋ฉด .then()์ ๋ถ์ด๋ฉด๋จ
๋์์ AJAX์์ฒญ ์ฌ๋ฌ๊ฐ ๋ ๋ฆฌ๊ธฐ
Promise.all( [axios.get('URL1'), axios.get('URL2')] )
url1 ,url2๋ก get์์ฒญ์ ๋์์ ํด์ค
๋๋ค ์๋ฃ ์ ํน์ ์ฝ๋๋ฅผ ์คํํ๊ณ ์ถ์ผ๋ฉด .then()๋ค์ ๋ถ์ด๋ฉด ๋จ
๐ ์๋ ์๋ฒ์ ๋ฌธ์์๋ฃ๋ง ์ฃผ๊ณ ๋ฐ๊ธฐ ๊ฐ๋ฅ
array / object ์ฃผ๊ณ ๋ฐ๊ธฐ ๋ถ๊ฐ๋ฅ โ ์๋ฃ์ ๋ฐ์ดํ๋ฅผ ์น๋ฉด ๊ฐ๋ฅ
"{"name" : "kim"}"
์ด๊ฑธ JSON ์ด๋ผ๊ณ ํฉ๋๋ค.
JSON์ ๋ฌธ์ ์ทจ๊ธ์ ๋ฐ๊ธฐ ๋๋ฌธ์ ์๋ฒ์ ์์ ๋กญ๊ฒ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค.
๊ทธ๋์ ์ค์ ๋ก ๊ฒฐ๊ณผ.data ์ถ๋ ฅํด๋ณด๋ฉด ๋ฐ์ดํ์ณ์ง JSON์ด ๋์์ผํ๋๋ฐ
axios ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ JSON -> object/array ๋ณํ์์ ์ ์๋์ผ๋ก ํด์ค์
์ถ๋ ฅํด๋ณด๋ฉด object/array๊ฐ ๋์ต๋๋ค.
fetch('URL').then(๊ฒฐ๊ณผ => ๊ฒฐ๊ณผ.json()).then((๊ฒฐ๊ณผ) => { console.log(๊ฒฐ๊ณผ) } )
์์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ธ fetch()๋ฅผ ์ด์ฉํด์ get/post ์์ฒญ์ด ๊ฐ๋ฅํ๋ฐ
์ด๊ฑด JSON โ object/array ๋ก ์๋์ผ๋ก ์๋ฐ๊ฟ์ฃผ๊ธฐ ๋๋ฌธ์ ์ง์ ๋ฐ๊พธ๋ ์์ ์ด ํ์
AJAX๋ก ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ html์ ๊ฝ์ ๋ ์๋ฌ๋๋ ์ด์
<div> {state.ใ
ใ
}</div>
์ด๋ state๊ฐ ๋น์ด์๋ค๊ณ ์๋ฌ๊ฐ ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
์ด์ ๋ ajax์์ฒญ๋ณด๋ค html๋ ๋๋ง์ด ๋ ๋นจ๋ผ์ ๊ทธ๋ด ์ ์์
state์์ ๋ญ๊ฐ ๋ค์ด์์ผ๋ฉด ๋ณด์ฌ๋ฌ๋ผ๊ณ if๋ฌธ ๊ฐ์๊ฑธ ์ถ๊ฐํ๋ฉด ๋จ
tab๋ง๋ค๊ธฐ
function Detail(){
let [ํญ, ํญ๋ณ๊ฒฝ] = useState(0)
return (
<Nav variant="tabs" defaultActiveKey="link0">
<Nav.Item>
<Nav.Link onClick={()=>{ ํญ๋ณ๊ฒฝ(0) }} eventKey="link0">๋ฒํผ0</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link onClick={()=>{ ํญ๋ณ๊ฒฝ(1) }} eventKey="link1">๋ฒํผ1</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link onClick={()=>{ ํญ๋ณ๊ฒฝ(2) }} eventKey="link2">๋ฒํผ2</Nav.Link>
</Nav.Item>
</Nav>
<TabContent ํญ={ํญ}/>
)
}
function TabContent(props){
if (props.ํญ === 0){
return <div>๋ด์ฉ0</div>
}
else if (props.ํญ === 1){
return <div>๋ด์ฉ1</div>
}
else if (props.ํญ === 2){
return <div>๋ด์ฉ2</div>
}
}
๋ค๋ฅธ๋ฐฉ๋ฒ
function TabContent(props){
return [ <div>๋ด์ฉ0</div>, <div>๋ด์ฉ1</div>, <div>๋ด์ฉ2</div> ][props.ํญ]
} //props.ํญ์ด 0์ด๋ฉด array์๋ฃ์์ 0๋ฒ์๋ฃ๋ฅผ ๊บผ๋ด์ค
props ์ฝ๊ฒ ์ฐ๋ ๋ฐฉ๋ฒ
function TabContent({ํญ}){
return [ <div>๋ด์ฉ0</div>, <div>๋ด์ฉ1</div>, <div>๋ด์ฉ2</div> ][ํญ]
}
์์์ปดํฌ๋ํธ์์ props๋ผ๊ณ ํ๋ผ๋ฏธํฐ๋ฅผ ํ๋๋ง ์๋ช ํ๋๊ฒ์๋๋ผ
{state1์ด๋ฆ, state2์ด๋ฆ..} ์ด๋ ๊ฒ ์์ฑํ๋ฉด props.state1์ด๋ฆ ์ด๋ ๊ฒ ์ํด๋ ๋จ
๐ ์ ๋๋ฉ์ด์ ๋ง๋ค๊ธฐ
.start {
opacity : 0
}
.end {
opacity : 1;
transition : opacity 0.5s;
}
useEffect๋ฅผ ์ฌ์ฉํด์ state์๋๋ฉด props๊ฐ ๋ณํ ๋๋ง๋ค ์ฝ๋์คํ
//์ด๊ฑด ์๋ณด์ end๋ฅผ ๋๋ค๊ฐ ๋ถ์ฌ์ผํจ
function TabContent({ํญ}){
let [fade, setFade] = useState('')
useEffect(()=>{
setFade('end')
}, [ํญ])
return (
<div className={'start ' + fade}>
{ [<div>๋ด์ฉ0</div>, <div>๋ด์ฉ1</div>, <div>๋ด์ฉ2</div>][ํญ] }
</div>
)
}
fade๋ผ๋ state๋ง๋ค๊ณ state์ ๋ฐ๋ผ className์ด ์ด๋ป๊ฒ ๋ณด์ผ์ง ์์ฑํ๊ณ ์ํ ๋ fade๋ณ๊ฒฝ
โ end๋ผ๋ ํด๋์ค๋ช ์ ๋ถ์ฐฉํ๋๊ฑด ๋ง๋๋ฐ ๋ผ์๋ค๊ฐ ๋ถ์ฌ์ผ ์ ๋๋ฉ์ด์ ์ด ๋ณด์
function TabContent({ํญ}){
let [fade, setFade] = useState('')
useEffect(()=>{
setTImeout(()=>{ setFade('end') }, 100) //์๊ฐ์ฐจ๋ฅผ ๋
return ()=>{
setFade('') //clean up function ์ฌ์ฉ
}
}, [ํญ])
return (
<div className={'start ' + fade}> // `start ${fade}`๊ฐ๋ฅ
{ [<div>๋ด์ฉ0</div>, <div>๋ด์ฉ1</div>, <div>๋ด์ฉ2</div>][ํญ] }
</div>
)
}
setTimeout ์ฌ์ฉํ๋ ์ด์
๋ฆฌ์กํธ 18๋ฒ์ ์ด์๋ถํฐ๋ automatic batch๋ผ๋ ๊ธฐ๋ฅ์ด ์๊ฒผ์
state๋ณ๊ฒฝํจ์๋ค์ด ์ฐ๋ฌ์์ ์ฌ๋ฌ๊ฐ ์ฒ๋ฆฌ๋์ด์ผํ๋ฉด state๋ณ๊ฒฝํจ์๋ค ๋ค ์ฒ๋ฆฌํ๊ณ ๋ง์ง๋ง์ ํ๋ฒ๋ง ์ฌ๋ ๋๋ง๋จ
๊ทธ๋์ โendโ๋ก ๋ณ๊ฒฝํ๋๊ฑฐ๋ โโ์ด๊ฑธ๋ก ๋ณ๊ฒฝํ๋๊ฑฐ๋ ์ฝ๊ฐ์ ์๊ฐ์ฐจ๋ฅผ ๋ฌ์ผํจ
ํน์ ์ปดํฌ๋ํธ ๋ก๋์ ํฌ๋ช ๋๊ฐ 0์์ 1๋ก ์์ํ ์ฆ๊ฐํ๋ ์ ๋๋ฉ์ด์ ์ฃผ๋ ๋ฐฉ๋ฒ
์ ์ผ ํฐ div๋ฐ์ค์ ํด๋์ค ํ๋ถ์ฐฉ
๋ถ๋ชจ์ปดํฌ๋ํธ์์ ์์์ปดํฌ๋ํธ์ ์์์ปดํฌ๋ํธ์ state ์ ์ก
App โ detailPage โ TabContent ๋ก props๋ฅผ 2๋ฒ ์ ์ก
์ด๊ฒ ๊ท์ฐฎ์ผ๋ฉด Context API๋ฌธ๋ฒ(๊ฑฐ์ ์ฌ์ฉ x) or Redux๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ
<TabContent tab = {tab} shoes = {props.shoes}></TabContent>
Context API๋ฌธ๋ฒ์ผ๋ก props์์ด state ๊ณต์ ํ๊ธฐ
Context API ๋ฌธ๋ฒ์ ์ฐ๋ฉด props์ ์ก์์ด๋ ์ฌ์ฉ๊ฐ๋ฅ
context๋ ์ฝ๊ฒ ๋น์ ํ์๋ฉด state๋ณด๊ดํจ
(App.js)
export let Context1 = React.createContext();
function App(){
let [์ฌ๊ณ , ์ฌ๊ณ ๋ณ๊ฒฝ] = useState([10,11,12]);
return (
<Context1.Provider value={ {์ฌ๊ณ , shoes} }>
<Detail shoes={shoes}/>
</Context1.Provider>
)
}
๋ง๋ Context๋ก ์ํ๋ ๊ณณ์ ๊ฐ์ธ๊ณ ๊ณต์ ๋ฅผ ์ํ๋ state๋ฅผ value์์ ๋ค ์ ์ผ๋ฉด ๋จ
๊ฐ์ผ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๊ทธ ์์ ์ปดํฌ๋ํธ๋ state๋ฅผ props์ ์ก์์ด ์ง์ ์ฌ์ฉ๊ฐ๋ฅ
Context ์์ ์๋ state๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด
(Detail.js)
import {useState, useEffect, useContext} from 'react';
import {Context1} from './../App.js';
function Detail(){
let {์ฌ๊ณ } = useContext(Context1) //Context๋ฅผ ํด์ฒดํด์ฃผ๋ ํจ์
return (
<div>{์ฌ๊ณ }</div>
)
}
//์ฌ์ง์ด Detail ์์ ์๋ ๋ชจ๋ ์์์ปดํฌ๋ํธ๋ useContext() ์ฐ๋ฉด ์์ ๋กญ๊ฒ ์ฌ๊ณ state๋ฅผ ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค.
Context API๋จ์ (์์ฐ๋ ์ด์ )
โ ์ด๊ฑฐ๋ณด๋ค Redux๊ฐ์ ์ธ๋ถ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉํจ
์ฅ๋ฐ๊ตฌ๋ ํ์ด์ง ๋ง๋ค๊ธฐ(Redux ์ฌ์ฉ)
table๋ ์ด์์์ ๋ถํธ์คํธ๋ฉ์์๊ฐ์ ธ์ด
Redux ์ฌ์ฉ์ ์ด์
Redux๋ props ์์ด state๋ฅผ ๊ณต์ ํ ์ ์๊ฒ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Redux๋ฅผ ์ค์นํด์ ์ฌ์ฉํ๋ฉด jsํ์ผ ํ๋์ state๋ค์ ๋ณด๊ดํ ์ ์๋๋ฐ ๊ทธ๊ฑธ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์ง์ ๊บผ๋ด์ธ ์ ์์
๊ทธ๋์ props์ ์ก์ด ํ์์์ด์ง โ ์ฌ์ดํธ๊ฐ ์ปค์ง๋ฉด ์ธ ์ ๋ฐ์ ์์
๊ฐ๋ฐ์ ๊ตฌ์ธ์์๋ redux๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋ จ๋๋ฅผ ๋๋ถ๋ถ ์๊ตฌํจ
Redux ์ค์น
npm install @reduxjs/toolkit react-redux
redux toolkit์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๋๊ฑด๋ฐ redux์ ๊ฐ์ ๋ฒ์ (๋ฌธ๋ฒ์ด ์ข ๋ ์ฌ์)
์ค์น ์ ์ฃผ์์ฌํญ
๋ฒ์ ์ด ๋ฎ์ผ๋ฉด 18.1.0์ด๋ ๊ฒ ์์ ํ๋ค ํ์ผ์ ์ฅํ๊ณ ํฐ๋ฏธ๋์์ installํ๋ฉด ๋จ
Redux์ธํ
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: { }
})
๊ทธ๋ฆฌ๊ณ ๋ฐ์ <Provider store={importํ ํ์ผ}>
์ด๊ฑธ๋ก<App/>
์ ๊ฐ์ธ๋ฉด ๋จ
โ <App>
๊ณผ ๊ทธ ๋ชจ๋ ์์์ปดํฌ๋ํธ๋ค์ store.js์ ์๋ state๋ฅผ ๋ง์๋๋ก ๊บผ๋ด์ธ์์์
import { Provider } from "react-redux";
import store from './store.js'
//importํด์ค๊ณ
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}> {/**<App>์ ๊ฐ์ธ๊ธฐ*/}
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>
);
Redux store์ state ๋ณด๊ดํ๋ ๋ฐฉ๋ฒ
import { configureStore, createSlice } from '@reduxjs/toolkit'
//์์ฑ
let user = createSlice({
name : 'user',
initialState : 'kim'
})
//๋ณด๋ด๊ธฐ
export default configureStore({
reducer: {
user : user.reducer
}
})
{ name : 'state์ด๋ฆ', initialState : 'state๊ฐ' }ย ์ด๊ฑฐ ๋ฃ์ผ๋ฉด state ํ๋ ์์ฑ๊ฐ๋ฅ
(createSlice( ) ๋ useState( ) ์ ์ฉ๋๊ฐ ๋น์ทํ๋ค๊ณ ๋ณด๋ฉด ๋จ)
{ ์๋ช : createSlice๋ง๋ ๊ฑฐ.reducer }ย ์ด๋ฌ๋ฉด ๋ฑ๋ก ๋
์ฌ๊ธฐ ๋ฑ๋กํ state๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์์ ๋กญ๊ฒ ์ฌ์ฉ๊ฐ๋ฅ
Redux store์ ์๋ state ๊ฐ์ ธ๋ค ์ฐ๋ ๋ฐฉ๋ฒ
(Cart.js)
import { useSelector } from "react-redux"
function Cart(){
let a = useSelector((state) => { return state } )
//let a = useSelector((state) => state) return๊ณผ ์ค๊ดํธ๋ ๋์์ ์๋ต๊ฐ๋ฅ
//let a = useSelector((state) => state.user ) ์ด๋ ๊ฒ user๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์ฌ์์์
console.log(a)
return (์๋ต)
}
์๋ฌด ์ปดํฌ๋ํธ์์ useSelector((state) => { return state } ) ์ฐ๋ฉด store์ ์๋ ๋ชจ๋ state๊ฐ ๊ทธ ์๋ฆฌ์ ๋จ์
store์ state๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ
state๋ฅผ ์์ ํด์ฃผ๋ ํจ์๋ถํฐ store.js์ ๋ง๋ค์ด๋๊ณ ์ปดํฌ๋ํธ์์ ์ํ ๋ ์คํํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๋ ์์ฑ
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : {
changeName(state){
return 'john ' + state
}
}
})
slice ์์ reducers : {}์ด๊ณ ์์ ํจ์๋ง๋ฌ
ํจ์์ ํ๋ผ๋ฏธํฐ ํ๋ ์๋ช ํ๋ฉด ๊ทธ๊ฑด ๊ธฐ์กด state๊ฐ ๋จ
return ์ฐ์ธก์ ์๋ก์ด state์ ๋ ฅํ๋ฉด๊ทธ๊ฑธ๋ก ๊ธฐ์กด state๋ฅผ ๊ฐ์์น์์ค
export let { changeName } = user.actions
slice์ด๋ฆ.actions ๋ผ๊ณ ์ ์ผ๋ฉด state๋ณ๊ฒฝํจ์๊ฐ ์ ๋ถ ํด๋น ์๋ฆฌ์ ์ถ๋ ฅ
๊ทธ๊ฑธ ๋ณ์์ ์ ์ฅํ๋ค๊ฐ exportํ๋ผ๋ ๋ป
(Cart.js)
import { useDispatch, useSelector } from "react-redux"
import { changeName } from "./../store.js"
(์๋ต)
let dispatch = useDispatch()
<button onClick={()=>{
dispatch(changeName())
}}>๋ฒํผ์</button>
store.js์์ ์ํ๋ state๋ณ๊ฒฝํจ์ ๊ฐ์ ธ์ค๊ณ
useDispatch๋ฅผ importํ๊ณ
dispatch(state๋ณ๊ฒฝํจ์()) ์ด๋ ๊ฒ ๊ฐ์ธ์ ์คํํ๋ฉด state๋ฅผ ๋ณ๊ฒฝํด์ค
โ state์์ ํด์ฃผ๋ ํจ์๋ฅผ ๋ถ๋ฌ์ ์์ ํ๋ ๋ฐฉ์์ผ๋ก ํ๋ ์ด์
์ปดํฌ๋ํธ์์ state๋ฅผ ์ง์ ์์ ํ๊ฒ๋๋ฉด ๋น์ฅ์ ํธํ์ง๋ง state๊ฐ ์๋ชป๋ณ๊ฒฝ๋๋ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๊ฒ๋๋ฉด
state๋ฅผ ์์ ํ ์ปดํฌ๋ํธ๋ฅผ ๋ชจ๋ ๋ค์ ธ์ ์ฐพ์์ผํจ
redux state๊ฐ array / object์ธ ๊ฒฝ์ฐ ๋ณ๊ฒฝํ๋ ค๋ฉด
{name : โkim, age : 20} ์ธ ์๋ฃ์์ kim โ park ์ด๋ ๊ฒ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ
return ์ค๋ฅธ์ชฝ์ ์ ์๊ฑธ๋ก ๊ธฐ์กด state๋ฅผ ๊ฐ์์น์์ค
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state){
state.name = 'park'
return {name : 'park', age : 20} //๋ณดํต ์ด๋ ๊ฒ ์ฌ์ฉ ์ํจ
}
}
})
state๋ฅผ ์ง์ ์์ ํ๋ผ๊ณ ํด๋ ๋ณ๊ฒฝ ์๋จ
state๋ฅผ ์ง์ ์์ ํ๋ ๋ฌธ๋ฒ์ ์ฌ์ฉํด๋ ์ ๋ณ๊ฒฝ๋๋ ์ด์ ๋
Immer.js ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ state ์ฌ๋ณธ์ ํ๋ ๋ ์์ฑํด์ค ๋๋ถ์ธ๋ฐ Redux ์ค์นํ๋ฉด ๋ธ๋ ค์์ ๊ทธ๋ ์ต๋๋ค.
๊ทธ๋์ ๊ฒฐ๋ก ์ array/object ์๋ฃ์ ๊ฒฝ์ฐ state๋ณ๊ฒฝ์
state๋ฅผ ์ง์ ์์ ํด๋ฒ๋ ค๋ ์ ๋๋๊น ์ง์ ์์ ํ์ญ์์ค.
โ ๋ณดํต state๋ฅผ ๋ง๋ค ๋ ๋ฌธ์๋ ์ซ์ ํ๋๋ง ํ์ํด๋ redux์์ ์ผ๋ถ๋ฌ object์๋๋ฉด array์ ๋ด๋ ๊ฒฝ์ฐ๊ฐ ์์ ์๋ํ๋ฉด ์์ ์ด ํธ๋ฆฌํด์ง๊ธฐ ๋๋ฌธ
state ๋ณ๊ฒฝํจ์๊ฐ ์ฌ๋ฌ๊ฐ ํ์ํ๋ฉด
ํ๋ผ๋ฏธํฐ๋ฌธ๋ฒ์ ์ฌ์ฉ๊ฐ๋ฅ
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
increase(state, action){
state.age += action.payload
}
}
})
ํ๋ผ๋ฏธํฐ์ ๋ ฅ์ ํด์ ํจ์์ฌ์ฉ์ด ๊ฐ๋ฅ
ํ๋ผ๋ฏธํฐ ์๋ฆฌ์ ๋ฃ์ ์๋ฃ๋ค์ .payloadํ๋ฉด ๋์ด
๋ณดํต ํ๋ผ๋ฏธํฐ๋ฅผ action ์ผ๋ก ์๋ช ๋ง์ดํจ
action.typeํ๋ฉด state๋ณ๊ฒฝํจ์ ์ด๋ฆ ๋์ด
action.payloadํ๋ฉด ํ๋ผ๋ฏธํฐ ๋์ด
๋ฒํผ ๋๋ฅด๋ฉด ์๋ +1๋๋ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
๋ฒํผ๋๋ฅด๋ฉด state๋ฅผ ์์ ํด์ผํ๋ state๋ฅผ +1ํด์ฃผ๋ ์์ ํจ์๋ถํฐ ์์ฑํ๊ณ export / import
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
state[action.payload].count++
}
}
})
์ ํํ๊ฒ ๋์ํ๋ ค๋ฉด ๋ฒํผ๋๋ฅด๋ฉด ๋๋ฅธ ์ํid๋ฅผ ๊ฐ์ ธ์์ ๊ฐ์ ธ์จ ์ํ id์ ๊ฐ์ id๋ฅผ ๊ฐ์ง ์ํ์ state์์ ์ฐพ์์ ๊ทธ๊ฑธ +1ํ๋๋ก ์ฝ๋์์ฑ
โ ์ด๋ ๊ฒ ํด์ผ ์ํ์์ ์ ๋ ฌ ๋ฑ ์์๊ฐ ๋ฐ๋์ด๋ ์ ๋์ํจ
dispatch(addCount(state.cart[i].id))
findIndex()๋ array๋ค์ ๋ถ์ผ ์ ์์
์์ ์ฝ๋ฐฑํจ์๋ฃ๊ณ return๋ค์ ์กฐ๊ฑด์์ ๋ฃ์ผ๋ฉด๋
ํ๋ผ๋ฏธํฐa๋ array์์ ์๋ ํ๋ํ๋์ ์๋ฃ
array์ ์๋ค ์๋ฃ๋ฅผ ๋ค ๊บผ๋ด์ ์กฐ๊ฑด์์ ๋์ ํด๋ณด๊ณ ์กฐ๊ฑด์์ด ์ฐธ์ด๋ฉด ๊ทธ๊ฒ ๋ช๋ฒ์งธ ์๋ฃ์ธ์ง ๋ฐํํด์ค
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
let num = state.findIndex((a)=>{
return a.id === action.payload })
state[num].count++
}
}
})
์ฃผ๋ฌธ๋ฒํผ๋๋ฅด๋ฉด state์ ์๋ก์ด ์ํ์ถ๊ฐ
state๋ณ๊ฒฝํจ์๋ง๋ค๊ณ exportํ๊ณ importํด์ ์ฌ์ฉ
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
state[action.payload].count++
},
addItem(state, action){
state.push(action.payload)
}
}
})
(Detail.js)
<div className="col-md-6">
<h4 className="pt-5">{findItem.title}</h4>
<p>{findItem.content}</p>
<p>{findItem.price}</p>
<button className="btn btn-danger" onClick={()=>{
//console.log(findItem.title)
dispatch(addStock( {id : findItem.id, name : findItem.title, count : 2} ))}}>์ฃผ๋ฌธํ๊ธฐ</button>
</div></div>
/cart์ ๋ ฅํด์ ํ์ด์ง๋ฅผ ์ด๋ํ๋ฉด ํ์ด์ง๊ฐ ์๋ก๊ณ ์นจ๋๊ธฐ๋๋ฌธ์ state๋ ์ด๊ธฐ๊ฐ์ผ๋ก ๋์๊ฐ โ ๋ผ์ฐํฐ๋ฒํผ์ ๋ง๋ค์ด์ ํ์ด์ง ์ด๋ํด์ผํจ
๋ฆฌ์กํธ์์ ์์ฃผ ์ฐ๋ if๋ฌธ ์์ฑํจํด 5๊ฐ
์ง๊ธ๊น์ง๋ ์ผํญ์ฐ์ฐ์๋ง ์ฌ์ฉ
function Component() {
if ( true ) {
return <p>์ฐธ์ด๋ฉด ๋ณด์ฌ์ค HTML</p>;
} else {
return null;
}
}
// ์๋์ฒ๋ผ ์ฌ์ฉํ๋ฉด else์๋ต์ด ๊ฐ๋ฅํจ
function Component() {
if ( true ) {
return <p>์ฐธ์ด๋ฉด ๋ณด์ฌ์ค HTML</p>;
}
return null;
}
์๋ฐ์คํฌ๋ฆฝํธ if๋ฌธ์ return() ์์ JSX ๋ด์์๋ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ
<div> if () {} </div>
๋ ์๋๊ธฐ ๋๋ฌธ์ ๋ณดํต return + JSX ์ ์ฒด๋ฅผ ๋ฑ์ด๋ด๋ if๋ฌธ์ ์์ฑํด์ ์ฌ์ฉ
์๋ฐ์คํฌ๋ฆฝํธ function์์์ return์ด๋ผ๋ ํค์๋๋ฅผ ๋ง๋๋ฉด return ๋ฐ์ ์๋ ์ฝ๋๋ ๋์ด์ ์คํ๋์ง ์์
if -> else if -> else ์ด๋ ๊ฒ ๊ตฌ์ฑ๋ ์กฐ๊ฑด๋ฌธ๋ if ๋๊ฐ๋ก ์ถ์ฝ๊ฐ๋ฅํฉ๋๋ค.
์กฐ๊ฑด๋ฌธ ? ์ฐธ์ผ๋ ์คํํ ์ฝ๋ : ๊ฑฐ์ง์ผ ๋ ์คํํ ์ฝ๋
function Component() {
return (
<div>
{
1 === 1
? <p>์ฐธ์ด๋ฉด ๋ณด์ฌ์ค HTML</p>
: null
}
</div>
)
}
- &&์ฐ์ฐ์๋ก if ์ญํ ๋์
true && '์๋
'; //์๋
์ถ๋ ฅ
false && '์๋
'; //false ์ถ๋ ฅ
true && false && '์๋
'; //false ์ถ๋ ฅ
์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ทธ๋ฅ &&๋ก ์ฐ๊ฒฐ๋ ๊ฐ๋ค ์ค์ ์ฒ์ ๋ฑ์ฅํ๋ false๊ฐ์ ์ฐพ์์ฃผ๊ณ ๊ทธ๊ฒ ์๋๋ฉด ๋ง์ง๋ง๊ฐ์ ๋จ๊ฒจ์ค
//์๋ ๋๊ฐ๋ ๋์ผํ ์ญํ
function Component() {
return (
<div>
{
1 === 1
? <p>์ฐธ์ด๋ฉด ๋ณด์ฌ์ค HTML</p>
: null
}
</div>
)
}
function Component() {
return (
<div>
{ 1 === 1 && <p>์ฐธ์ด๋ฉด ๋ณด์ฌ์ค HTML</p> }
</div>
)
}
&&์ฐ์ฐ์๋ก ์กฐ๊ฑด์๊ณผ ์ค๋ฅธ์ชฝ JSX์๋ฃ๋ฅผ ๋น๊ต
์ผ์ชฝ ์กฐ๊ฑด์์ด true๋ฉด ์ค๋ฅธ์ชฝ JSX๊ฐ ๊ทธ ์๋ฆฌ์ ๋จ์
์ผ์ชฝ ์กฐ๊ฑด์์ด false๋ฉด false๊ฐ ๋จ์ (false๊ฐ ๋จ์ผ๋ฉด HTML๋ก ๋ ๋๋งํ์ง ์์)
โ๋ง์ฝ ๋ณ์๊ฐ ์ฐธ์ด๋ฉด
๋ฅผ ์ด ์๋ฆฌ์ ์ถ๋ ฅํ๊ณ ์๋๋ฉด nullโ ์ด๋ฐ ์ํฉ์์ ์์ฃผ ์ฌ์ฉ
- switch / case ์กฐ๊ฑด๋ฌธ
๊ธฐ๋ณธ ๋ฌธ๋ฒ์ธ๋ฐ if๋ฌธ์ด ์ค์ฒฉํด์ ์ฌ๋ฌ๊ฐ ๋ฌ๋ ค์๋ ๊ฒฝ์ฐ ๊ฐ๋ ์ฌ์ฉ
function Component2(){
var user = 'seller';
switch (user){
case 'seller' :
return <h4>ํ๋งค์ ๋ก๊ทธ์ธ</h4>
case 'customer' :
return <h4>๊ตฌ๋งค์ ๋ก๊ทธ์ธ</h4>
default :
return <h4>๊ทธ๋ฅ ๋ก๊ทธ์ธ</h4>
}
}
1.ย switch (๊ฒ์ฌํ ๋ณ์){}ย ์ด๊ฑฐ๋ถํฐ ์์ฑํ๊ณ
๊ทธ ์์ย case ๊ฒ์ฌํ ๋ณ์๊ฐ์ด๊ฑฐ๋์ผ์นํ๋ :ย ๋ฅผ ๋ฃ์ด์ค๋๋ค.
๊ทธ๋์ ์ด๊ฒ ์ผ์นํ๋ฉด case : ๋ฐ์ ์๋ ์ฝ๋๋ฅผ ์คํํด์ค๋๋ค.
4.ย default :ย ๋ ๊ทธ๋ฅ ๋งจ ๋ง์ง๋ง์ ์ฐ๋ else๋ฌธ๊ณผ ๋์ผํฉ๋๋ค.
์ฅ์ : if๋ฌธ์ ์ฐ๋ฌ์ ์ธ ๋ ์ฝ๋๊ฐ ์ฝ๊ฐ ์ค์ด๋ฌ / ๋จ์ : ์กฐ๊ฑด์๋์์ ๋ณ์ ํ๋๋ง ๊ฒ์ฌ ๊ฐ๋ฅ
- object / array ์๋ฃํ ์์ฉ
๊ฒฝ์ฐ์ ๋ฐ๋ผ์ ๋ค๋ฅธ htmlํ๊ทธ๋ค์ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๊ฒฝ์ฐ์ if๋ฌธ ์ฌ๋ฌ๊ฐ ํน์ ์ผํญ์ ์ฌ์ฉํ ์ ์์ง๋ง ์๋์ฒ๋ผ๋ ์์ฑ ๊ฐ๋ฅ
ํ์ฌย state๊ฐ info๋ฉด <p>์ํ์ ๋ณด</p>
ํ์ฌย state๊ฐ shipping์ด๋ฉด <p>๋ฐฐ์ก์ ๋ณด</p>
ํ์ฌ state๊ฐ refund๋ฉด <p>ํ๋ถ์ฝ๊ด</p>
function Component() {
var ํ์ฌ์ํ = 'info';
return (
<div>
{
{
info : <p>์ํ์ ๋ณด</p>,
shipping : <p>๋ฐฐ์ก๊ด๋ จ</p>,
refund : <p>ํ๋ถ์ฝ๊ด</p>
}[ํ์ฌ์ํ]
}
</div>
)
}
์๋ JSX ์์์ html ํ๊ทธ๋ค์ ์ ๋ ๊ฒ object์ ๋ด๋ , array์ ๋ด๋ ์๋ฌด ์๊ด์์ต๋๋ค.
์ํผ ์ด๋ ๊ฒ object ์๋ฃํ์ผ๋ก HTML์ ๋ค ์ ๋ฆฌํด์ ๋ด์ ๋ค์
๋ง์ง๋ง์ object{} ๋ค์ [] ๋๊ดํธ๋ฅผ ๋ถ์ฌ์ย "key๊ฐ์ดย ํ์ฌ์ํ์ธ ์๋ฃ๋ฅผ ๋ฝ๊ฒ ์ต๋๋ค"ย ๋ผ๊ณ ์จ๋๋๊ฒ๋๋ค.
var ํญUI = { //๋ณดํต var๋ณ์๋์ state๋ก ์ฌ์ฉํจ
info : <p>์ํ์ ๋ณด</p>,
shipping : <p>๋ฐฐ์ก๊ด๋ จ</p>,
refund : <p>ํ๋ถ์ฝ๊ด</p>
}
function Component() {
var ํ์ฌ์ํ = 'info';
return (
<div>
{
ํญUI[ํ์ฌ์ํ]
}
</div>
)
}
localStorage ๋ฌธ๋ฒ
jsํ์ผ ์๋ฌด๋ฐ์๋ localStorage๋ฌธ๋ฒ์ ์ฐ๋ฉด localStorage์ ๋ฐ์ดํฐ์ ์ถ๋ ฅ ๊ฐ๋ฅ
๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋๊ฑด ๋ถ๊ฐ๋ฅํ๊ธฐ๋๋ฌธ์ ๊บผ๋ด์ ์์ ํ๊ณ ๋ค์ ์ ์ฅ
localStorage.setItem('๋ฐ์ดํฐ์ด๋ฆ', '๋ฐ์ดํฐ'); //์ ์ฅ
localStorage.getItem('๋ฐ์ดํฐ์ด๋ฆ'); //์ฝ๊ธฐ
localStorage.removeItem('๋ฐ์ดํฐ์ด๋ฆ') //์ญ์
localStorage์ array/object ์๋ฃ๋ฅผ ์ ์ฅํ๋ ค๋ฉด
๊ทธ๋ฅํ๋ฉด ์๋ฃ๊ฐ ๊นจ์ง๊ธฐ ๋๋ฌธ์ JSON์ผ๋ก ๋ณํํด์ ์ ์ฅ
localStorage.setItem('obj', JSON.stringify({name:'kim'}) );
//๋ณํํด์ ์ ์ฅ
var a = localStorage.getItem('obj'); //data๊ฐ์ ธ์ด
var b = JSON.parse(a) //JSON -> array/object
์ต๊ทผ ๋ณธ ์ํ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
(Detail.js)
useEffect(()=>{
let ๊บผ๋ธ๊ฑฐ = localStorage.getItem('watched')
๊บผ๋ธ๊ฑฐ = JSON.parse(๊บผ๋ธ๊ฑฐ)
๊บผ๋ธ๊ฑฐ.push(์ฐพ์์ํ.id)
localStorage.setItem('watched', JSON.stringify(๊บผ๋ธ๊ฑฐ))
}, [])
์ค๋ณต์ ๊ฑฐ
์ํid๊ฐ ์ด๋ฏธ [] ์์ ์กด์ฌํ๋ฉด ์ถ๊ฐํ์ง ์๋๋ก if๋ฌธ ์์ฑ ํ๊ฑฐ๋
Set์๋ฃํ์ผ๋ก array์ ์ค๋ณต ์ ๊ฑฐ
(Detail.js)
useEffect(()=>{
let ๊บผ๋ธ๊ฑฐ = localStorage.getItem('watched')
๊บผ๋ธ๊ฑฐ = JSON.parse(๊บผ๋ธ๊ฑฐ)
๊บผ๋ธ๊ฑฐ.push(์ฐพ์์ํ.id)
//Set์ผ๋ก ๋ฐ๊ฟจ๋ค๊ฐ ๋ค์ array๋ก ๋ง๋ค๊ธฐ
๊บผ๋ธ๊ฑฐ = new Set(๊บผ๋ธ๊ฑฐ)
๊บผ๋ธ๊ฑฐ = Array.from(๊บผ๋ธ๊ฑฐ) //๋ค์ array๋ก
localStorage.setItem('watched', JSON.stringify(๊บผ๋ธ๊ฑฐ))
}, [])
localStorage์ state๋ฅผ ์๋์ ์ฅ๋๊ฒ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด
redux-persist ์ด๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์นํด์ ์ฐ๋ฉด redux store ์์ ์๋ state๋ฅผ ์๋์ผ๋ก localStorage์ ์ ์ฅํด์ค๋๋ค.
state ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ทธ์ ๋ง๊ฒ localStorage ์ ๋ฐ์ดํธ๋ ์์์ ํด์ค
ํ์ง๋ง ์ ํ ๋ฌธ๋ฒ ๋ณต์กํ๊ณ ๊ท์ฐฎ์ต๋๋ค.
๊ทธ๋์ ์์ฆ์ ์ ๊ท ์ฌ์ดํธ๋ค์ Redux ๋์ Jotai, Zustand ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ ์ ํ ๋ ๊ฑฐ์ ํ์์๊ณ ๋ฌธ๋ฒ์ด ํจ์ฌ ๋ ์ฌ์ฐ๋๊น์.
๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค๋ ์๋ง localStorage ์๋์ ์ฅ๊ธฐ๋ฅ๋ค์ด ์์ต๋๋ค.
react-query ์ ๋ฐ์ดํธ ์ฌํญ
(์ ๋ฐ์ดํธ ์ฌํญ)ย ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ์ด react-query์์ @tanstack/react-query๋ก ๋ฐ๋์ด์ ์๋ ์ ๋ฆฌํ๊ฒ๋ค์์ ๋ณ๊ฒฝํด์ ์ฌ์ฉํ ๊ฒ
npm install @tanstack/react-query //์ค์น์ ๋ณ๊ฒฝ์ฌํญ
//import์ ๋ณ๊ฒฝ์ฌํญ
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'
//useQuery ์ธ๋ '์๋ช
' ๋ง๊ณ ['์๋ช
']์ผ๋ก ๋ฐ๋
useQuery(['์๋ช
'],
ajax์์ฒญํ๋ค๋ณด๋ฉด ํด๋น ๊ธฐ๋ฅ๋ค์ด ๊ฐ๋ ํ์ํด์ง
-๋ช์ด๋ง๋ค ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ค๊ฒ ํ๋ ค๋ฉด
-์์ฒญ ์คํจ์ ๋ช์ด ๊ฐ๊ฒฉ์ผ๋ก ์ฌ์๋
-๋ค์ ํ์ด์ง ๋ฏธ๋ฆฌ ๊ฐ์ ธ์ค๊ธฐ
-ajax ์ฑ๊ณต/์คํจ ์ ๊ฐ๊ฐ ๋ค๋ฅธ html์ ๋ณด์ฌ์ฃผ๋ ค๋ฉด
โ์ง์ ๊ฐ๋ฐํด๋๋์ง๋ง ๊ท์ฐฎ์ผ๋ฉด react-query๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ ์ฌ์ฉํด๋๋จ
sns, ์ฝ์ธ๊ฑฐ๋์ ๊ฐ์ ์ค์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ค์ผํ๋ ์ฌ์ดํธ๋ค์์ ์ฌ์ฉํ๋ฉด ์ ์ฉํ๊ณ ๋๋จธ์ง ์ฌ์ดํธ๋ค์ ๋ฑํ ์ธ๋ฐ๋ ์์
ํฐ๋ฏธ๋์์ npm install react-queryํ๊ณ
index.jsํ์ผ์์ 1๋ฒ 2๋ฒ 3๋ฒ ์์๋๋ก
import { QueryClient, QueryClientProvider } from "react-query" //1๋ฒ
const queryClient = new QueryClient() //2๋ฒ
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<QueryClientProvider client={queryClient}> //3๋ฒ
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</QueryClientProvider>
);
react-query๋ก ajax์์ฒญํ๋ ๋ฐฉ๋ฒ
๊ทธ๋ฅ ์์ฒญํด๋๋์ง๋ง react-query๋ฅผ ์จ์ ajax์์ฒญ์ ๋ ๋ฆฌ๋ฉด ๋ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ์ ๊ณต / useQuery()๋ก ajax์์ฒญ์ ๊ฐ์ธ์ ์ฌ์ฉ
function App(){
let result = useQuery('์๋ช
', ()=>
axios.get('https://codingapple1.github.io/userdata.json')
.then((a)=>{ return a.data })
)
}
react-query ์ฅ์
์ฅ์ 1. ajax ์์ฒญ ์ฑ๊ณต/์คํจ/๋ก๋ฉ์ค ์ํ๋ฅผ ์ฝ๊ฒ ํ์ ํ ์ ์์ต๋๋ค.
function App(){
let result = useQuery('์๋ช
', ()=>
axios.get('https://codingapple1.github.io/userdata.json')
.then((a)=>{ return a.data })
)
return (
<div>
{ result.isLoading && '๋ก๋ฉ์ค' }
{ result.error && '์๋ฌ๋จ' }
{ result.data && result.data.name }
</div>
)
}
result๋ผ๋ ๋ณ์์ ajax ํ์ฌ ์ํ๊ฐ ์์์ ์ ์ฅ๋ฉ๋๋ค.
๊ทธ๋์ ajax ๋ก๋ฉ์ค์ผ ๋ <A/>
๋ณด์ด๊ธฐ / ajax ์ฑ๊ณต์์ <B/>
๋ณด์ด๊ธฐ
์ด๋ฐ๊ฑฐ ์ง์ ๊ฐ๋ฐํ๋ ค๋ฉด state ๋ถํฐ ๋ง๋ค์ด์ผ ํ์ํ ๋ฐ ์๋ ๊ทธ๋ด ํ์๊ฐ ์์ต๋๋ค.
์ฅ์ 2. ํ๋ง๋๋ฉด ์์์ ajax ์ฌ์์ฒญํด์ค๋๋ค.
ํ์ด์ง์์ ์ผ์ ์๊ฐ ๊ฒฝ๊ณผ / ๋ค๋ฅธ์ฐฝ์ผ๋ก ๊ฐ๋ค๊ฐ ๋์์ค๊ฑฐ๋ ์ด๋ด๋ ์์์ ajax์์ฒญ์ ๋ค์ํด์ค / ์ฌ์์ฒญ๋๋๋ฒ, ์ฌ์์ฒญ ๊ฐ๊ฒฉ ์กฐ์ ํ๋ ๋ฐฉ๋ฒ๋ ์์
์ฅ์ 3. ์คํจ์ ์ฌ์๋ ์์์ ํด์ค
๋ช๋ฒ ์ฌ์๋ํ๊ณ ์๋๋ฉด ์ค๋ฅ๋์์ค
์ฅ์ 4. ajax๋ก ๊ฐ์ ธ์จ ๊ฒฐ๊ณผ๋ state ๊ณต์ ํ์์์
์ง๊ธ App ์ปดํฌ๋ํธ์์ ์ ์ ์ด๋ฆ ๊ฐ์ ธ์ค๋ ajax ์์ฒญ์ ๋ ๋ฆฌ๊ณ ์์ต๋๋ค.
๊ทผ๋ฐ ๊ทธ ์ ์ ์ด๋ฆ ๊ฒฐ๊ณผ๊ฐ Detail ์ปดํฌ๋ํธ์๋ ํ์ํ๋ฉด?
์ ์ ์ด๋ฆ์ props ์ ์กํ๋ฉด ๋์ง๋ง props ์ ์ก ํ์์์
Detail ์ปดํฌ๋ํธ์๋ค๊ฐ ์ ์ ์ด๋ฆ ajax ์์ฒญํ๋ ์ฝ๋ ๋๊ฐ์ด ๋ ์ ์ผ๋ฉด ๋ฉ๋๋ค.
react-query๋ ์ค๋งํธํ๊ธฐ ๋๋ฌธ์ ajax ์์ฒญ์ด 2๊ฐ๋ ์์ผ๋ฉด 1๊ฐ๋ง ๋ ๋ ค์ฃผ๊ณ
์บ์ฑ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ๊ฐ์ ajax ์์ฒญ์ ํ ์ ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฐ์ ๊ฐ์ ธ์์ ์๋๋ค.
react-query๊ฐ ์ฃผ์ฅํ๋ ์ฅ์ ์
server-state (DB ๋ฐ์ดํฐ)๋ฅผ ํ๋ก ํธ์๋์์ ์ค์๊ฐ ๋๊ธฐํํด์ฃผ๋๊ฑธ ๋์์ค๋ค๊ณ ํฉ๋๋ค.
๊ทผ๋ฐ ajax ์์ฒญ์ ๋ช์ด๋ง๋ค ๊ณ์ ๋ ๋ ค์ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ด๋ผ ์ข ๋นํจ์จ์ ์ผ ์๋ ์์ต๋๋ค.
์ค์๊ฐ์ผ๋ก ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฃผ ๋ณด๋ด๋ ค๋ฉด ์น์์ผ์ด๋ Server-sent events ๊ฐ์ ๊ฐ๋ฒผ์ด ๋ฐฉ์๋ค๋ ์์ต๋๋ค.
๊ทธ๋์ react-query๋ ajax ๊ด๋ จ ๊ธฐ๋ฅ๊ฐ๋ฐ ํธํ๊ฒ ํ ์ ์๋๋ฐ์ ์์๊ฐ ๋ ์์ต๋๋ค.
RTK Query ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์
Redux Toolkit ์ค์นํ ๊ฒฝ์ฐ RTK Query ๋ผ๋๊ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅํ๋ฐ
๋น์ทํ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํฉ๋๋ค.
๋ค๋ง ์ ํ ํ๋ ์ฝ๋๊ฐ ์ข ๋๋ฝ์ต๋๋ค.
RTK Query๋ ์ค์ ๋ค๋ฅธ ์ฉ๋๋ก๋ ๋ง์ด ์ฐ๋๋ฐ
ajax ์์ฒญํ Redux state ๋ณ๊ฒฝ์ ํ๊ณ ์ถ๋ค๋ฉด...
์๋ Redux state๋ณ๊ฒฝํจ์ ์์์ ajax์์ฒญํ๋ฉด ์๋์ด์ ์ปดํฌ๋ํธ ์์์ ํด์ผํฉ๋๋ค.
๊ทผ๋ฐ ajax ์์ฒญํ๋ ์ฝ๋๊ฐ ๋ค์ํ๊ณ ๋ง์ผ๋ฉด ์ปดํฌ๋ํธ ์์ ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ณ ๊ด๋ฆฌ๋ ๊ท์ฐฎ์๋ฐ
๊ทธ๋ฐ๊ฑธ Slice ์์์ ๊ด๋ฆฌ๊ฐ๋ฅํ๊ฒ ๋์์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ajax ์์ฒญํ๋ ์ฝ๋๊ฐ 100๋ง๊ฐ ์์ผ๋ฉด ๊ทธ๊ฑธ ํธ๋ฆฌํ๊ฒ ๊ด๋ฆฌํ ์ ์๊ฒ ๋์์ค๋๋ค.
๊ทผ๋ฐ ์ฝ๋๊ฐ ์ฝ๊ฐ ๋๋ฌ์ธ ๋ฟ