[ JavaScript / React ] 리액트 연습
환경 : Visual Studio Code
이전글과 이어지는 연습 입니다 (참고 : https://ggingggang05.tistory.com/219)
[ 실습 1 : 은행 이체 화면 문제 ]
- Ex04.js
//import
import { useState } from "react";
//function
function Ex04(){
const [money, setMoney] = useState(0);
return(
<>
<h2>은행 이체 화면 문제</h2>
<hr/>
<input type="text" value={money} readOnly></input>원
<hr/>
<button onClick={e=>setMoney(money + 1000000)}>100만</button>
<button onClick={e=>setMoney(money + 500000)}>50만</button>
<button onClick={e=>setMoney(money + 100000)}>10만</button>
<button onClick={e=>setMoney(money + 50000)}>5만</button>
<button onClick={e=>setMoney(money + 10000)}>1만</button>
<button onClick={e=>setMoney(0)}>정정</button>
</>
);
}
//export
export default Ex04;
(+) 입력창에 사용자가 임의로 숫자를 입력하지 못하도록 하여 아래와 같은 오류 방지
(+) '정정'을 제외하고 금액 누적이 되도록 설정
[ 실습 2 : 입력 이벤트 ]
- Ex05.js
//import
import { useMemo, useState } from "react";
//function
function Ex05(){
//state
const [memberId, setMemberId] = useState("");
//(+추가) memberId가 변하면 그에 따른 글자 수와 형식검사를 진행하고 싶다
//const count = memberId.length;
const count = useMemo(()=>{
return memberId.length;
}, [memberId]);
// const isValid = /^[a-z][a-z0-9]{7,19}$/.test(memberId);
const isValid = useMemo(()=>{
const regex = /^[a-z][a-z0-9]{7,19}$/;
return regex.test(memberId);
}, [memberId]);
return(
<>
<h1>화면5번 - 입력이벤트</h1>
아이디를 입력하세요
<br/>
<input type="text" value={memberId}
onChange={e=>setMemberId(e.target.value)}/>
<br/>
입력 글자 수 : {count}
<br/>
형식 검사 결과 : {isValid ? '합격' : '불합격'}
</>
);
}
//export
export default Ex05;
(+) 입력창은 표시와 변경이 동시에 일어나는 컴포넌트로, 표시만 하면 변경이 일어나지 않는다.
(1) value로 표시하고 onChange로 변경
(2) value로 표시하고 readOnly로 변경이 불가능하도록 변경
위와 같은 두 가지 방법으로 변경을 진행해야 한다. (실습 1의 오류 메세지도 이 말을 하고 있다.)
(+) React에서는 this를 쓰지 않는다
- 이벤트에서 this 대신 e.target 키워드를 사용한다
- 입력값은 this.value가 아니라 e.target.value가 된다
(+) state - 화면의 근원 데이터, useState로 선언
(+) memo - state에서 계산하는 데이터, useMemo(함수, [감지항목])로 선언
(+추가) this와 e.target의 차이
- e.target이 더 구체적이고 명확하게 타겟을 정한다고 볼 수 있다
[ 실습 3 : 실습2응용 - 객체로 관리해보자 ]
- Ex07.js
//import
import { useMemo, useState } from "react";
//function
function Ex07(){
//Ex06에서 사용한 네 개의 state를 하나의 객체로 관리할 수 있는가?
const [score, setScore] = useState({
java:0, react:0, db:0, design:0
});
//function(함수) - 코드가 길어질 때 쉽게 사용할 수 있도록 함수를 생성
//function 이름(매개변수) {코드}
//const 이름 = (매개변수) => {코드}
//function changeScore(e) {}
const changeScore = (e) =>{
//다른 건 건드리지 않고 이벤트가 발생한 항목의 점수만 변경
//- 입력 창에 반드시 state 객체와 동일한 이름이 있어야 함(e.target.name)
//- 입력값을 알아야 한다(e.target.value)
const name = e.target.name;
//const value = parseInt(e.target.value == '' ? 0 : e.target.value);
//const value = parseInt(e.target.value || 0);
const value = e.target.value !== "" ? parseInt(e.target.value) : 0;
setScore({
...score, //전개연산자, score의 나머지는 유지하세요 (전개 연산자는 배열 또는 객체를 하나하나 넘기는 용도로 사용)
[name] : value //객체의 항목 중 name에 해당하는 항목을 value로 변경, 이름을 변수처리하겠다
});
};
//memo
const total = useMemo(()=>{
return score.java + score.react + score.db + score.design;
}, [score]);
const average = useMemo(()=>{
return total / 4;
}, [total]);
return (
<>
<h1>화면 7번 - 객체 state</h1>
자바 <input type="text" name="java" value={score.java} onChange={changeScore} />
<br/>
리액트 <input type="text" name="react" value={score.react} onChange={changeScore} />
<br/>
DB <input type="text" name="db" value={score.db} onChange={changeScore} />
<br/>
디자인 <input type="text" name="design" value={score.design} onChange={changeScore} />
<hr />
총점 : {total}점
<br/><br/>
평균 : {average}점
</>
);
}
//export
export default Ex07;
코드에 주석 달아 놓았으니 참고하도록~!
개인 공부 기록용입니다:)