뷰에 렌더링돼야 하는 컴포넌트의 데이터를 저장하는데 사용한다.
즉, 사용자가 입력이나 행동으로 값이 변경될 때 컴포넌트는 리렌더링이 필요한데 이를 STATE에서 변경된 부분을 저장한다.
리액트가 아닌 경우, 일반 자바스크립트를 쓴 브라우저는 노드정보가 바뀔때마다 노드트리를 처음부터 다시 생성한다. 하지만 리액트는 가상돔을 써서 우리 시야에 보이는 부분만 수정해서 보여주고 모든 업데이트가 끝나면 일괄로 합쳐서 실제 돔에 적용한다.
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter(counter+1);
};
retrun(code);
React.useState() 배열에서 보통 데이터에는 counter처럼 원하는대로 붙이고 f는 set 뒤에 데이터 이름을 붙인다.
어떤값을 부여하던 setCounter 함수는 그 값으로 업데이트하고 리렌더링 일으킨다.
1. counter라는 데이터를 받음
2. return()에 그 데이터를 담고 있음 (리턴은 사용자가 보게될 컴포넌트)
3. 버튼이 클릭되면 counter값을 바꿔줄 함수 호출 -> setCounter
4. counter의 새로운 값을 가지고 counter 함수를 호출
5. 그 새로운 값은 setCounter(counter + 1)에 써준 counter + 1
<script type="text/babel">
const root = document.getElementById("root");
// let counter =0;
// function countUp() {
// counter +=1;
// render();
// }
// //계속 리렌더링을 해줘야하기에 좋은 방법이 아님
// function render() {
// ReactDOM.render(<Container/>, root);
// }
function App() {
//리렌더링(컴포넌트 재생성)의 역할(modifier이 state를 변경)
//[현재값, 데이터를 수정하기 위한 함수]
const [counter, setCounter] = React.useState(0);
const onClick = () => {
// state 세팅1(직접할당)
setCounter(counter+1);
// state 변경2(함수할당) 더 안전. current가 현재 값이라는 걸 확실히 보장
setCounter((current)=> current +1);
};
return(
<div>
<h3>Total clicks : {counter}</h3>
<button onClick={onClick}>Click me</button>
</div>
);
}
ReactDOM.render(<App/>, root);
</script>
<script type="text/babel">
const root = document.getElementById("root");
function MinutesToHours() {
const [amount, setAmount] = React.useState();
//minutes > hours 변환할 때 한 쪽 수정 방지
const [fliped, setFlipped] = React.useState(false);
const onChange=(event)=> {
setAmount(event.target.value);
};
const reset = ()=> {
setAmount(0);
};
const onFlip =()=> {
reset();
setFlipped((current)=>!current);
};
return(
<div>
<div>
<label htmlFor="minutes">Minutes</label>
<input value={fliped ? Math.round(amount*60) : amount} id="minutes" placehoder="Minutes" type="number" onChange={onChange} disabled={fliped==true}/>
</div>
<div>
<label htmlFor="hours">Hours</label>
<input value={fliped ? amount : Math.round(amount/60)} id="hours" placehoder="Hours" type="number" onChange={onChange} disabled={fliped==false}/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
);
};
function KmtoMiles() {
const [amount, setAmount] = React.useState();
const [flipped, setFliepped] = React.useState(false);
const onChange =(event)=> {
setAmount(event.target.value);
}
const reset =()=> {
setAmount(0);
}
const onFlip =()=> {
reset();
setFliepped((current)=>!current);
}
return(
<div>
<div>
<label htmlFor="Km">Km</label>
<input value={flipped?amount*1.609:amount} id="km" placehoder="KM" type="number" onChange={onChange} disabled={flipped}/>
</div>
<div>
<label htmlFor="Miles">Miles</label>
<input value={flipped?amount:amount/1.609} id="miles" placehoder="Miles" type="number" onChange={onChange} disabled={!flipped}/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
)
}
function App() {
const [index, setIndex] = React.useState("xx");
const onSelect =(event) =>{
setIndex(event.target.value);
};
return(
<div>
<h1>Super Converter</h1>
<select value={index} onChange={onSelect}>
<option value="xx">Select your units</option>
<option value="0">Minutes & Hours</option>
<option value="1">Km & Miles</option>
</select>
{index == "xx" ? "Please select your units" : null}
{index == "0" ? <MinutesToHours/> : null}
{index == "1" ? <KmtoMiles/> : null}
</div>
);
};
ReactDOM.render(<App/>, root);