React 기초

  1. React
    1. 사용하기
    2. JSX
      1. Counter 만들기
    3. State
      1. 방법 1. State를 이용하여 Counter 만들기
      2. 방법 2. State를 이용하여 Counter 만들기
      3. 연습1. 환율 계산기
      4. 예제2. Time Converter
      5. 예제3. Distance Converter
    4. Props
      1. memo
      2. propTypes

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의 문법 차이

JSJSX
classclassName
forhtmlFor

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,
}

=> 타입이 맞지 않다면 경고 메세지를 보여준다.