React 기초
React
- 페이스북이 만들었으며 UI를 손쉽게 만들어주는 라이브러리이다.
- React Native는 React JS 기반이다.
- SPA(Single Page Application) 형식이다.
- JSX(JavaScript Xml) 문법으로 HTML을 작성한다.
FIXME: 아래 역할 수정하기 babel
- 최신 자바스크립트 문법으로 변경해주는 라이브러리 webpack
- 코드를 포장해서 모듈 번들러
사용하기
- React & React Dom을 import 해야한다. 방법 1. 복잡한 방식 - span 생성하기
index.html
<body></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>
const root = document.getElementById("root");
const span = React.createElement("span",{id:"hello-span"}, "Hello Span!!");
ReactDOM.render(span, root);
</script>
💡💡💡
React: 상호작용하도록 만들어주는 라이브러리
React: Dom: React element를 HTML에 두는 역할
render: 사용자에게 보여준다.
=> 결과
<body>
<div id="root">
<span id="hello-span">Hello Span!!</span>
</div>
</body>
방법.2 간단한 방식
- JSX
JSX
- JS를 확장한 문법
- HTML과 비슷함
JSX를 이해시키기 위해 babel 사용
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
Counter 만들기
<script type="text/babel">
const root = document.getElementById("root");
let counter = 0;
function countUp() {
counter += 1;
ReactDOM.render(<Container />, root);
}
const Title = () => (
<h3 id="title">
Total Click: {counter}
</h3>)
const Button = () => (
<button
onClick={countUp}
>
Click Me
</button>
);
const Container = () => (
<div>
<Title />
<Button />
</div >
);
ReactDOM.render(<Container />, root);
</script>
=> 현재 onClick 이벤트가 진행될 때마다 렌더링을 한다.
💡 컴포넌트의 첫 글자는 대문자여야 한다. => 소문자면 JSX는 HTML 태그라고 인식함
⭐Vanila JSX와 React JS의 차이점⭐
- Vanila JS: body 전체를 업데이트한다.
- React JS: 바뀐 부분만 업데이트한다.
JS와 JSX의 문법 차이
| JS | JSX |
| class | className |
| for | htmlFor |
React의 특징
- rendering 할 때 바뀐 부분만 refresh 해준다.
- 데이터가 바뀔 때마다 컴포넌트를 리렌더링하고 UI를 Refresh 한다.
State
state 확인하기
data = React.useState(0);
console.log(data);
결과 =>
Array [ 0, Me() ]
0: 0
1: function Me()
length: 2
data[0] //데이터
data[1] //데이터를 변경해줄 함수
방법 1. State를 이용하여 Counter 만들기
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter(counter + 1)
};
return (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={onClick}>Click Me</button>
</div>
)
};
const Container = () => (
<div>
<App />
</div >
);
ReactDOM.render(<Container />, root);
</script>
방법 2. State를 이용하여 Counter 만들기
const onClick = () => {
setCounter((current) => current + 1)
}
💡 current //state의 현재 값
=> 혹여나 값이 바뀔 때를 대비하여 방법 2가 더 안전한 방법이다.
연습1. 환율 계산기
function App() {
const [money, setMoney] = React.useState(0);
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
setMoney(event.target.value);
};
const Reset = () => {
setMoney(0);
};
const onFlip = () => {
setFlipped((current) => !current);
};
return (
<div>
<h1 className="Hello">Convertor</h1>
<div>
<label htmlFor="money">KRW</label>
<input id="money" value={flipped ? ((money * 1383).toFixed(2)) : money} placeholder="원" type="number" onChange={onChange} disabled={flipped}></input>₩
<label htmlFor="dollar">USD</label>
<input id="dollar" value={flipped ? money : (money / 1383).toFixed(2)} placeholder="달러" type="number" onChange={onChange} disabled={!flipped}></input>$
<button onClick={Reset}>리셋</button >
<button onClick={onFlip}>전환</button >
</div>
</div >
)
};
💡 반올림
dollar = 1000.789
정수 반올림 Math.round(dollar)
=> 1001소수점 자리 반올림 dollar.toFixed(2)
=> 1000.79
예제2. Time Converter
function MinutesToHours() {
const [time, setTime] = React.useState(0);
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
setTime(event.target.value);
};
const reset = () => {
setTime(0);
}
const onFlip = () => {
reset();
setFlipped((current) => !current);
}
return (
<div>
<h2 className="title__time">Time Converter</h2>
<div>
<label htmlFor="minutes">Minutes</label>
<input
value={flipped ? Math.round(time * 60) : time}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
disabled={flipped === true} />
</div>
<div>
<label htmlFor="hours">Hours</label>
<input
value={flipped ? time : Math.round(time / 60)}
id="hours" placeholder="Hours"
type="number"
onChange={onChange}
disabled={flipped === false} />
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>Invert</button>
</div >
);
}
예제3. Distance Converter
function KmToMiles() {
const [distance, setDistance] = React.useState(0);
const [invert, setInvert] = React.useState(false);
const onChange = (event) => {
setDistance(event.target.value);
}
const reset = () => setDistance(0);
const onInvert = () => {
reset();
setInvert((current) => !current)
}
return (
<div>
<h2>Km to Mile</h2>
<div>
<label htmlFor="km"> KM </label>
<input value={invert ? Math.round(distance * 1.609) : distance} id="km" placeholder="Km" type="number" onChange={onChange} disabled={invert === true} />
</div>
<div>
<label htmlFor="mile"> MILE </label>
<input value={invert ? distance : Math.round(distance / 1.609)} id="mile" placeholder="Mile" type="number" onChange={onChange} disabled={invert === false} />
</div>
<button onClick={reset}>Reset</button>
<button onClick={onInvert}>Invert</button>
</div>
)
}
Props
- 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법이다.
function Btn({ hello, changeValue }) {
return (
<button
onClick={changeValue}
style={{
backgroundColor: "green",
color: "white",
padding: "10px 20px",
border: "solid 1px",
borderRadius: 10,
fontSize: "16px",
}}> {hello}
</button >
)
}
function ConfirmBtn() {
return <button>Confirm</button>
}
const MemorizedBtn = React.memo(Btn);
function App() {
const [value, setValue] = React.useState("Save Changes")
const changeValue = () => setValue("Revert Changes");
return (
<div>
<MemorizedBtn hello={value} changeValue={changeValue} />
<MemorizedBtn hello="Continue" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
<Btn hello={value} changeValue={changeValue} />
<Btn hello="Continue" />
memo
- 부모 컴포넌트에 state 변경이 있을 때 자식들이 re-rendering하는 것을 막아주기 위해 사용한다.
memo 적용
const MemorizedBtn = React.memo(Btn);
<MemorizedBtn hello={value} changeValue={changeValue} />
<MemorizedBtn hello="Continue" />
=> 자신의 props가 바뀌지 않는다면 re-render 하지 않는다.
propTypes
- 어떤 타입의 prop을 받고 있는지 체크해준다.
script 추가
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
Btn.propTypes = {
hello: PropTypes.string.isRequired,
fontSize: PropTypes.number,
}
=> 타입이 맞지 않다면 경고 메세지를 보여준다.