60분을 입력하면 1시간을 출력해주고, 2시간을 입력하면 120분을 출력해주는 변환기가 있다면?
그리고 그런 변환기를 직접 만들어볼 수 있다면?
그걸 인적성 응용수리 풀 때 사용할 수 있다면? (그건 안된다 )
노마드코더 리액트JS를 수강하며 직접 만들어보았다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<script type="text/babel">
function MinutesToHours() {
const [amount, setAmount] = React.useState("");
const [flipped, 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>{" "}
{/* class는 className, for는 htmlFor로 지정*/}
<input
value={flipped ? amount * 60 : amount}
id='minutes'
placeholder='Minutes'
type='number'
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor='hours'>Hours</label>
<input
value={flipped ? amount : Math.round(amount / 60)}
id='hours'
placeholder='Hours'
type='number'
onChange={onChange}
disabled={!flipped}
/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>{flipped ? "H -> M" : "M -> H"}</button>
</div>
);
}
function KmToMiles() {
const [amount, setAmount] = React.useState("");
const [flipped, 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='kilometers'>Kilometer</label>{" "}
{/* class는 className, for는 htmlFor로 지정*/}
<input
value={flipped ? amount / 0.6214 : amount}
id='kilometer'
placeholder='kilometer'
type='number'
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor='mile'>mile</label>
<input
value={flipped ? amount : amount * 0.6214}
id='mile'
placeholder='miles'
type='number'
onChange={onChange}
disabled={!flipped}
/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>{flipped ? "M -> K" : "K -> M"}</button>
</div>
);
}
function App() {
const [index, setIndex] = React.useState("xx");
const onSelect = (event) => {
setIndex(event.target.value);
};
console.log("render w/", index);
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>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
APP이라는 부모 컴포넌트에 분<->시간 단위변환기와 킬로미터<->마일 단위 변환기라는 2개의 자식 컴포넌트를 렌더링한 것이다.
⭐️
const [amount, setAmount] = React.useState("");
React.useState()의 괄호 안에는 state의 디폴트 값을 지정해줄 수 있다.
내 단위 변환기에서 amount의 디폴트값은 ""이다. flipped의 디폴트값은 false이다.
분을 입력하는 input에서 숫자를 변경할 때 변경된 숫자(amount)를 보여주고 싶다면? input에 onChange함수를 걸고 event를 인자로 전달한다. setAmount가 modify해주는 함수이므로 event.target.value를 setAmount의 인자로 설정하면 된다!
flipped 상태도 마찬가지. 초기에 flipped되지 않은 상태라면? button에 onFlip함수를 걸어놓고, 현재 state인 false를 true로 변경할 수 있다. false 상태라면 시간input을 disabled로 막아놓아 분 단위만 입력할 수 있도록 하고, true 상태라면 분input을 disabled로 막아놓아 시간만 입력할 수 있도록 했다.
니꼬쌤의 팁!
setFlipped((current) => !current);
modifier함수의 인자 부분을 함수로 지정해주어야만 혹여나 다른 곳에서 업데이트가 일어나도 이를 반영할 수가 있다.
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>
);
아주 멋진 select 태그 ^^
각 옵션의 index를 지정해놓고(0 또는 1), 선택한 값에 따라 렌더링할 컴포넌트를 정하는 것이다.
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
html에 설정해놓은 root 태그에 App을 렌더링하기 위해 마지막 줄을 잊지 말 것! (물론 코드 마지막에 있다고 해서 마무리할 때 써야 하는 코드는 아니다 ㅋㅋㅋ 진작 rendering 해놓으려면 초반에 신경써야 할 관문이라고 할 수 있지 !)