[React] Movie-app Notes - State Practice
📒 Nomad Coder ReactJS로 영화 웹 서비스 만들기
강의노트 (2021 Updated ver.)
# 4. State Practice
Converter 만들기
분 -> 시간, 시간 -> 분으로 환산하는 변환기를 만들어보자.
1. State 생성
const [minutes, setMinutes] = React.useState();
const onChange = (e) => {
setMinutes(e.target.value);
}
minutes에는 아무 값도 선언하지 않았고, onChange
함수를 선언해 이벤트 발생 시 target(=input)의 값을 state의 값으로 set하도록 설정했다.
2. return (UI)
<div>
<h1 className="title">Converter</h1>
<label htmlFor="min">Minutes </label>
<input
id="min"
placeholder="Minutes"
type="number"
value={minutes} // state val === input val
onChange={onChange} // onChange: 변화가 있을 때마다 감지하는 func
/>
<h4>You are going to convert {minutes} to</h4>
<label htmlFor="hrs">Hours </label>
<input id="hrs" placeholder="Hours" type="number" />
</div>
📌 Check Point
JavaScipt가 선점한 단어를 JSX에서 쓰면 오류가 발생한다. 둘은 엄연히 다른 언어이다.
JSX에서label
의 속성으로for
을 쓰면 오류가 발생한다. 이는 JS 언어이기 때문이다. 마찬가지로class
를 쓰면 오류가 발생한다.
JSX에서 해당 속성을 부여하기 위해서는 아래와 같이 적용해야 한다.<JS> <JSX> for === HtmlFor class === ClassName
가장 처음 선언한 onChange()
함수를 input의 onChange={}
속성에 걸어 설정하면서, input 값에 변화가 있을 때마다 state 값(=minutes)가 해당 값으로 업데이트되고 이 값은 input value로 보여지게 된다. (input val === state val)
키보드 입력(이벤트 발생)
-> target(=input) value 감지
-> state 값으로 set
-> input value UI로 표기
Final Code
위 코드 플로우를 바탕으로, 호환이 가능한 Converter을 구현한다.
1. 시간 -> 분
2. 분 -> 시간
<script type="text/babel">
const root = document.getElementById("root")
function App() {
// create State
const [amount, setAmount] = React.useState(0);
const [flip, setFlip] = React.useState(false);
const onChange = (e) => {
// console.log(e.target.value);
setAmount(e.target.value);
}
const reset = () => setAmount(0);
const onflip = () => {
reset();
setFlip(current => !current);
console.log(flip);
} // 현재 flip값의 반대
return (
(
<div>
<h1 className="title">Converter</h1>
<div>
<label htmlFor="min">Minutes </label>
<input
id="min"
placeholder="Minutes"
type="number"
value={flip ? amount * 60 : amount}
// state val === input val
onChange={onChange} // onChange: 변화가 있을 때마다 감지하는 func
disabled={flip} // == disabled={flip === true}
// flip일 때 disabled되니까 flip이면 시간입력가능
// ==> flip일때는 시간값*60으로 min 인풋창에 보여져야함.
// ==> 아니라면 amount 그대로 보여져야함
/>
</div>
<div>
<label htmlFor="hrs">Hours </label>
<input
id="hrs"
placeholder="Hours"
type="number"
value={flip ? amount : Math.round(amount / 60)}
onChange={onChange}
disabled={!flip} // == disabled={flip === false}
// flip이 false이면 입력불가능
// flip이 true일 경우, 입력값 그대로 표기,
// 아니라면 60으로 나누어 표기
/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onflip}>{flip ? '->Change to *Mins to Hrs*' : '->Change to *Hrs to Mins*'}</button>
</div>
)
)
}
ReactDOM.render(<App />, root);
</script>
📌 Check Point
- if문 함수로 표현하는 대신 삼항연산자로 간단한 알고리즘 구현
- contents를 state로 표현 (ex. button 내용 변경)
Super Converter 만들기
select
, option
로 선택사항을 추가해보자.
function MinsToHrs() {...}
function KmToMile() {...}
function App() {
const [index, setIndex] = React.useState('0');
const onSelect = (e) => setIndex(e.target.value);
return (
(
<div>
<h1 className="title">Super Converter</h1>
<select value={index} onChange={onSelect}>
<option value="0">Minutes / Hours</option>
<option value="1">km / Mile</option>
</select>
{index === '0' ? <MinsToHrs /> : null}
{index === '1' ? <KmToMile /> : null}
</div>
)
)
}
📌 Check Point
state
를 바꾸면 해당 컴포넌트 - 연계 컴포넌트는 re-rendering 된다. 무조건!- 속성으로
value
를 가질 수 있으면onChange
속성을 붙일 수 있다.- 속성값을 컨트롤해서 로직을 만드는 연습을 하자.
덧붙이는 Code
위의 코드를 참고하여 KM -> MILE Converter를 만들었다.
function KmToMile() {
const [amount, setAmount] = React.useState(1);
const [km, setKm] = React.useState(true);
const onChange = (e) => {
setAmount(e.target.value)
};
const reset = () => setAmount('');
const onKm = () => {
reset();
setKm(cur => !cur) // 이게 바뀌면 disabled에 영향을 주니까.
}
return (
<div>
<h3>KM to MILE</h3>
<div>
<label htmlFor="km">Km </label>
<input
type="number"
id="km"
value={km ? amount : (amount / 1.609).toFixed(2)}
onChange={onChange}
disabled={!km}
/>
</div>
<div>
<label htmlFor="mile">Mile </label>
<input
type="number"
id="mile"
value={km ? (amount * 1.609).toFixed(2) : amount}
onChange={onChange}
disabled={km}
/>
</div>
<div>
<button onClick={onKm}>{km ? 'Change Mile converter' : 'Change Km Converter'}</button>
</div>
<div>
<button onClick={reset}>reset</button>
</div>
</div>
)
Flow
km값을 시작으로, km 모드이면 mile이 disabled
-> km value 입력
-> target value로 amount state 변경
-> km 모드이므로 km칸 amount 그대로 표기,
mile칸 *1.609, 소수점 2자리까지 표기(.toFixed()
)
-> mode change
->onKm()
발동
-> 입력값 / 계산값 리셋,
km 현재 값이true
였으므로false
로 변환
->km === false
이므로 km칸 disabled, mile칸 abled
-> mile converter 사용가능
Overall Summary
이 일련의 과정으로 로직을 갖는 컴포넌트를 분리해 생성하는 연습을 했다.
* 컴포넌트 : App(), MinsToHrs(), KmToMile()
각 로직에 따라 컴포넌트로 독립개체로 분할하면 사용성과 효율이 상승하고, 필요에 따라 재사용도 가능하다. 쉽게 말해 요소를 컨트롤하기 쉬워진다.
분할 => 정복
여기서 생각해 볼 문제
모든 컴포넌트가 방금 구현한 것처럼 한 페이지에 몰려있다면?
나중에 앱이 고도로 발전해 1억개의 단위환산이 필요하게 된다면, 우리는 1억개의 컴포넌트를 한 페이지에서 관리해야 한다. 이것은 매우 비효율적이다.
컴포넌트는 각각 로직에 따라 분류되어져야 할 것이고, 분리된 컴포넌트들을 잘 연결해 데이터 전달이 용이하도록 만들어야 오류없는 애플리케이션을 구현할 수 있을 것이다.
독립적으로 분류된 컴포넌트를 더 효율적으로 관리하기 위해 필요한 것이 Props이다.
그렇다면 이제 Props를 알아보자.
Author And Source
이 문제에 관하여([React] Movie-app Notes - State Practice), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@qeiqiem/React-Movie-app-Notes-State-Practice저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)