Sparta/항해99

항해 사전준비 6-7일차 - React.js

또롱또 2022. 5. 5. 07:19
728x90

벌써 7일차다.

 

JSX - 자바스크립트를 확장한 문법.

- 생긴게 HTML이랑 비슷하다.

 

// jsx를 사용한 react
const title = <span id="title" onMouseEnter={()=>console.log("mouse enter")}>HI React</span>

// jsx를 사용안한 react
const title = React.createElement("span", {id:"title", onMouseEnter:()=>console.log("mouse enter"), "HI React");

JSX를 사용하는 쪽은 그냥 HTML이라고 해도 무방할정도다..

 

Babel - JSX로 적은 코드를 브라우저가 이해할수 있는 형태로 변환해준다.

 

JS로 button을 만들어 클릭시 count를 세면, html의 button, span 그리고 innerText가 모두 동시에 업데이트 된다.

하지만 React는 오로지 바껴야하는 부분, innerText만 업데이트가 된다.

- data가 바뀔때마다(modify) 컴포넌트를 re-rendering하고 UI를refresh한다.

 

 State 기본

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
    </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 src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        const root = document.getElementById("root");
        function App(){
            const [counter, setCounter] = React.useState(0);
            // const counter = data[0];
            // const modifier = data[1];
            const onClick = () =>{
                //setCounter(counter + 1);
                // 현재의 state를 가지고 새로운 값을 계산 -> more 안전
                setCounter((current)=>current+1);
            }
            return (
                <div>
                    <h3>Total Clicks:{counter}</h3>
                    <button onClick={onClick}>Click Me</button>
                </div>
            );
        }

        ReactDOM.render(<App />, root)

    </script>
</html>

 

시간/km 변환기

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
    </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 src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        function MinutesToHours() {
        const [amount, setAmount] = React.useState(0);
        const [inverted, setInverted] = React.useState(false);
        const onChange = (event) => {
        setAmount(() => event.target.value);
        };
        const onInverted = () => {
        setInverted((current) => !current);
        return setAmount(() => 0);
        };
        return (
            <div>
                <h3>Minutes to Hours</h3>
                <div>
                    <label htmlFor="minutes">Minutes</label>
                    <input value={inverted ? amount * 60 : amount} id="minutes" placeholder="Minutes" type="number"
                        onChange={onChange} disabled={inverted} />
                </div>
                <div>
                    <label htmlFor="Hours">Hours</label>
                    <input value={inverted ? amount : Math.round(amount / 60)} id="Hours" placeholder="Hours" type="number"
                        disabled={!inverted} onChange={onChange} />
                </div>
                <button onClick={()=> setAmount(() => 0)}>Reset</button>
                <button onClick={onInverted}>
                    {inverted ? "Turn back" : "Invert"}
                </button>
            </div>
            );
        }

        function KmToMiles(){
            const [amount, setAmount] = React.useState(0);
            const [inverted, setInverted] = React.useState(false);
            const onChange = (event) => {
                setAmount(() => event.target.value);
            };
            const onInverted = () => {
                setInverted((current) => !current);
                return setAmount(() => 0);
            };
            return (
                <div>
                    <h3>KM to Miles</h3>
                    <div>
                        <label htmlFor="Miles">Miles</label>
                        <input value={inverted ? Math.round(amount / 1.62) : amount} id="Miles" placeholder="Miles"
                            type="number" disabled={inverted} onChange={onChange} />
                    </div>
                    <div>
                        <label htmlFor="km">KM</label>
                        <input value={inverted ? amount  : Math.round(amount * 1.62)} id="km" placeholder="Kilometers" type="number"
                            onChange={onChange} disabled={!inverted} />
                    </div>
                    
                    <button onClick={()=> setAmount(() => 0)}>Reset</button>
                    <button onClick={onInverted}>
                        {inverted ? "Turn back" : "Invert"}
                    </button>
                </div>
            );
        }
        
        function App(){
            const [index, setIndex] = React.useState("xx");
            const onSelect = (event) =>{
                setIndex(event.target.value)
            }
            return (
                <div>
                    <h1>Super Converter</h1>
                    <select value={index} onChange={onSelect}>
                        <option value="xx">Select</option>
                        <option value="0">Minutes & Hours</option>
                        <option value="1">KM & Miles</option>
                    </select>
                    {index === "xx" ? "Select": null}
                    {index === "0" ? <MinutesToHours /> : null}
                    {index === "1" ? <KmToMiles /> : null}
                </div>
            );
        }

        const root = document.getElementById("root");
        ReactDOM.render(<App />, root)

    </script>
</html>

 

Props 기본

<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
    </body>
    <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.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">

        function Btn({text, onClick}){
            return <button 
            onClick={onClick}
            style={{
                backgroundColor: "tomato",
                color: "white",
                padding: "10px 20px",
                border: 0,
                borderRadius: "10px",
            }}>{text}</button>
        }

        // 만약에 state에 변경이있으면, 모든건 다시 그려지는데(reload안하고 싶은것도 됌), 근데 memo()를 쓰면 props가 변경된거만 다시 그려준다.
        const MemorizedBtn = React.memo(Btn);

        function App(){
           const  [value, setValue] = React.useState("Save Changes");
           const changeValue = () => setValue("Revert Changes");
            return (
                <div>  
                    {/*props와 event listener는 다른개념, 여기서는 props의 개념으로밖에 안쓰임,
                    이벤트 리스너는 위의 컴포넌트에서 줄 수 밖에 없다.*/}
                    <MemorizedBtn text={value} onClick={changeValue} />
                    <MemorizedBtn text={1} />
                </div>
            );
        }

        const root = document.getElementById("root");
        ReactDOM.render(<App />, root)

    </script>
</html>

 

 

React 설치부터 다시 정리

개발환경 - node.js를 받고

터미널에 아래처럼 넣어준다.

제일뒤의 . 은 현재 디렉토리에 설치한다는 뜻이다.

npx create-react-app .

 

설치 후 안내받은 명령어

npm start 
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

npm start로 시작을 하고나면

3000포트에 샘플 리액트 앱을 띄워준다.

 

Node.js에서

포트 열린거 확인 

netstat -ano

포트 강제종료

taskkill /pid 23432 /f

// 숫자 부분에는 내가 종료하고자하는 포트의 pid를 넣는다.

 

Prop Types 설치

npm i prop-types

Prop Types import

import PropTypes from "prop-types"

Prop Type 예제

Button.propTypes = {
    text: PropTypes.string.isRequired,
}

 

React에서 CSS는 독립적으로 파일을 만들고,css를 사용할 js파일로 import 한다음에 사용이 가능하다.

import PropTypes from "prop-types"
import styles from "./Button.module.css"

// css 파일에 .btn이라는 클래스 이름으로 만들었다.

function Button({text}){
    return <button className={styles.btn}>{text}</button> 
}

Button.propTypes = {
    text: PropTypes.string.isRequired,
}

export default Button;

 

 

useEffect() - 코드가 딱 한번만 실행될수 있도록 도와준다.

useEffect(()=> {
  실행될 내용
},[]) // 빈 array를 넣으면 처음에 한번만 실행된다.
  // [keyword] 를 넣으면 keyword가 나올때마다만 실행된다.

정리(clean-up)를 이용하는 Effects

useEffect(() => {
... // 컴포넌트 렌더링 시 실행할 코드
return () => {
... // 컴포넌트가 화면에서 사라질 때 실행할 코드 (Clean-up)
}
}, []);
728x90