Vanilla JS와 다른 React의 장점은 바뀌려고 하는 데이터가 업데이트 될 때, Vanilla는 바뀌는 데이터가 포함된 태그 전체를 새로고침하는 반면, 리액트는 바뀌는 부분만을 새로고침해준다.
vanilla 에서는
span.innerText = `total clicks : ${counter}`;
로 표현하여 버튼의 클릭 수 변수를 태그의 innerText에 넣어줬다면, 리액트의 JSX는
<h3>Total Clicks : {counter}</h3>
와 같이 백틱을 사용하지 않고 중괄호에 변수명을 넣어준다.
버튼을 클릭하면 클릭 수를 화면에 표시해주는 코드
const root = document.getElementById("root"); let counter = 0; function countUp() { counter = counter + 1; ReactDOM.render(<Container />, root); } const Container = () => <div> <h3>Total Clicks : {counter}</h3> <button onClick={countUp}>Click Me!</button> </div> ReactDOM.render(<Container />, root);
countUp 함수에서 클릭을 할 때마다 새로 렌더링을 하여 화면에 보이는 숫자를 계속 업데이트 해준다.
인터렉티브하게 변수값을 화면에 노출시켜주려면은 계속 바뀌는 값 전체에 re-rendering함수를 사용해야 하는 것은 아니다.
React.useState()
함수 안에는 state를 변경해주고 싶은 값, 그리고 그것을 바꾸는 function을 리스트 형태로 넣을 수 있다.
const data = React.useState(0,countUp);
const counter = data[0];
const modifier = data[1];
위에서 0이 counter 값, countUp함수가 modifier로 들어가는 것이다.
그리고 보통은 아래와 같이 한번에 변수를 할당해준다.
const [counter, modifier] = React.useState(0);
function App() {
let [counter, setCounter] = React.useState(0);
function onClick() {
setCounter(counter + 1);
}
return (
<div>
<h3>Total Clicks : {counter}</h3>
<button onClick={onClick}>Click Me!</button>
</div>)
}
App 컴포넌트를 봤을 때 SetCounter가 counter의 값을 바꿔주는 함수이다. 이는 setCounter(counter + 1)
과 같이 안에 return될 counter값을 바로 넣어주면 된다.
setCounter는 counter값을 바꿔주는 동시에 화면에 렌더링도 새로 해줘 따로 렌더링 함수가 필요 없다.
앞서 설명한대로 지정된 변수 값을 직접 변경하는 형태로 modifying 함수를 작성할 수도 있지만 변수 값에 직접 접근하는 것이므로, 변수가 다른 곳에서 바뀌었을 수 있으므로 안정된 방법이 아니다.
이에 대비하여 그 변수의 현재 상태에 따른 값 변경
을 위하여 current
키워드를 사용한다.
function onClick() {
setCounter(current => current + 1);
}
current는 useState의 0번째 값의 현재 값을 뜻하는 키워드이다.
HTML의 사용법과 완전히 동일하게 JSX를 작성하면 일반적으로 큰 무리는 없지만, class속성이나, label태그의 for 속성은 JSX에서는
class - className
for - htmlFor
등으로 바꿔 사용해야 한다.
function App() {
const [minutes, setMinutes] = React.useState();
const onChange = (event) => {
setMinutes(event.target.value)
}
return (
<div>
<h1>Super Converter</h1>
<label for="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder='Minutes'
type="number"
onChange={onChange} />
<h4>You want to convert {minutes}</h4>
<label for="hours">Hours</label>
<input id="hours" placeholder='Hours' type="number" />
</div>
);
}
js의 event를 가져와 그 event(여기서는 onChange event)의 target의 value값을 가져오면 현재 내가 input에 입력하고 있는 값을 가져와 useState로 minutes에 값을 넣을 수 있다.
전체코드
<!DOCTYPE html> <html> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const root = document.getElementById("root"); function App() { const [minutes, setMinutes] = React.useState(); const onChange = (event) => { setMinutes(event.target.value) } const reset = () => setMinutes(0); return ( <div> <h1>Super Converter</h1> <label for="minutes">Minutes</label> <input value={minutes} id="minutes" placeholder='Minutes' type="number" onChange={onChange} /> <h4>You want to convert {minutes}</h4> <label for="hours">Hours</label> <input value={minutes / 60} id="hours" placeholder='Hours' type="number" /> <div> <button onClick={reset}>reset</button> </div> </div> ); } ReactDOM.render(<App />, root); </script> </html>
hour 박스에서 useState로 받은 minutes를 hour로 변환시키고, reset 버튼을 만들고 setMinutes를 통해 minutes를 0으로 reset 해주는 코드이다.