prop 과 state의 공통점은 각각의 값이 변경되면 새로운 return 값을 만들어 ui를 바꿈
차이점은 prop은 컴포넌트를 사용하는 외부자를 위한것 state는 컴포넌트를 만드는 내부자를 위한것
function App() {
const mode = 'WELCOME';
const topics = [
{id:1, title:'html', body:'html is ...'},
{id:2, title:'css', body:'css is ...'},
{id:3, title:'javascript', body:'javascript is ...'}
]
let content = null;
if(mode === 'WELCOME') {
content = <Article title="Welcome" body="Hello, WEB"></Article>
}else if (mode === 'READ') {
content = <Article title="Read" body="Hello, Read"></Article>
}
return (
<div>
<Header title="WEB" onChangeMod={()=>{
mode = 'WELCOME';
}}></Header>
<Nav topics={topics} onChangeMod={(id)=>{
mode = 'READ';
}}></Nav>
{content}
</div>
);
}
mode의 값이 mode === 'WELCOME' 또는 mode === 'READ' 로 바뀌면 <Article> 의 값이 바뀌어야 하는데 바뀌지 않음.
컴포넌트가 다시 렌더링되지 않기 때문
따라서 값을 바꾸기 위해서는 state가 필요
사용법
import {useState} from 'react';
const _mode = useState('WELCOME');
_mode 를 콘솔에 찍어 보면 배열 형태로 되어 있음
0번째는 현재 상태 값
1번째는 변경을 위한 값
정리하면
const _mode = useState('WELCOME');
const mode = _mode[0];
const setMode = _mode[1];
이것을 축약하면
const [mode, setMode] = useState('WELCOME');
따라서 값을 바꾸려면 아래와 같이 사용하게 됨
실행하면 상태값이 바뀜, 이유는 setMode로 인해서 상태값이 바뀌면 컴포넌트를 다시 렌더링하면서 mode의 값을 바꿈
예제)
function App() {
const [mode, setMode] = useState('WELCOME');
const [id, setId] = useState(null);
const topics = [
{id:1, title:'html', body:'html is ...'},
{id:2, title:'css', body:'css is ...'},
{id:3, title:'javascript', body:'javascript is ...'}
]
let content = null;
if(mode === 'WELCOME') {
content = <Article title="Welcome" body="Hello, WEB"></Article>
}else if (mode === 'READ') {
let title, body = null;
for(let i = 0; i < topics.length; i++) {
if(topics[i].id === id) {
title = topics[i].title;
body = topics[i].body;
}
}
content = <Article title={title} body={body}></Article>
}
return (
<div>
<Header title="WEB" onChangeMod={()=>{
setMode('WELCOME');
}}></Header>
<Nav topics={topics} onChangeMod={(_id)=>{
setMode('READ');
setId(_id);
}}></Nav>
{content}
</div>
);
}
export default App;
function Nav(props) {
const lis = [];
for(let i = 0; i < props.topics.length; i++) {
let t = props.topics[i];
lis.push(<li key={t.id}>
<a id={t.id} href={'/read/'+t.id} onClick={event=>{
event.preventDefault();
props.onChangeMod(Number(event.target.id));
}}>{t.title}</a>
</li>);
}
return <nav>
<ol>
{lis}
</ol>
</nav>
}
결과
마지막으로 state의 값을 변경하여 컴포넌트를 렌더링 하는 방법이 타입별로 다르다
const[value, setValue] = useState(PRIMITIVE); -> 원시 데이터 타입일 경우(string, number, bigint, boolean, undefined, symbol, null)
원시 타입일 경우 기존대로 seValue(newValue) 로 하면 컴포넌트가 다시 렌더링됨
const[value, setValue] = useState(Object); -> 범 객체일 경우(object, array)
object 객체일 경우
newValue = {...value} -> value값을 복제해서 newValue에 담음
newValue 변경
setValue(newValue)
array 배열일 경우
newValue = [...value] -> value값을 복제해서 newValue에 담음
newValue 변경
setValue(newValue)