[Nomad] ReactJS로 영화 웹 서비스 만들기 2

웹/React.js 2024. 1. 2. 09:00

노마드코더 강의 2일차.

심심해서 만들어보는 React JS 강의 수강

 - ReactJS로 영화 웹 서비스 만들기

  1. 준비물

     > 바닐라 JS에 대한 기초 지식, Visual Studio Code

     > 바닐라 JS 기초 강의 참고(무료)

     > React JS : https://unpkg.com/react@18/umd/react.production.min.js

     > React-Dom : https://unpkg.com/react-dom@18/umd/react-dom.production.min.js

     > Babel : https://unpkg.com/@babel/standalone/babel.min.js

 

 

* Minutes <-> Hours 단위 변환 계산기 샘플 만들어보기

1. Minutes <-> Hours 단위 변환 계산기 (기초)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
  <!-- 운영모드 React : React JS 엔진 역할-->
  <!-- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->
  <!-- 운영모드 React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <!--개발모드 React -->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!--개발모드 React-dom-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    function App() {
      const [amount, setMinutes] = React.useState();
      const [flipped, setFlipped] = React.useState(false);
      const onChange = (event) => {
        setMinutes(event.target.value);
      };
      const reset = () => setMinutes(0);
      const onFlip = () => {
        reset();
        setFlipped((current) => !current);
      };
      return (
        <div>
          <h1>Super Converter</h1>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={flipped ? amount * 60 : amount}
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              disabled={flipped}
            />
          </div>
          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={flipped ? amount : Math.round(amount / 60)}
              id="hours"
              placeholder="Hours"
              type="number"
              onChange={onChange}
              disabled={!flipped}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>Flip</button>
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

2. Minutes <-> Hours, Km <-> Miles 단위 변환 계산기
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
  <!-- 운영모드 React : React JS 엔진 역할-->
  <!-- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->
  <!-- 운영모드 React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <!--개발모드 React -->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!--개발모드 React-dom-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    function MinutesToHours() {
      const [amount, setMinutes] = React.useState();
      const [inverted, setInverted] = React.useState(false);
      const onChange = (event) => {
        setMinutes(event.target.value);
      };
      const reset = () => setMinutes(0);
      const OnInvert = () => {
        reset();
        setInverted((current) => !current);
      };
      return (
        <div>
          <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"
              onChange={onChange}
              disabled={!inverted}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={OnInvert}>
            {inverted ? "Turn back" : "Invert"}
          </button>
        </div>
      );
    }
    function KmToMiles() {
      const [distance, setMiles] = React.useState();
      const [inverted, setInverted] = React.useState(false);
      const onChange = (event) => {
        setMiles(event.target.value);
      };
      const reset = () => setMiles(0);
      const OnInvert = () => {
        reset();
        setInverted((current) => !current);
      };
      return (
        <div>
          <div>
            <label htmlFor="Km">Km</label>
            <input
              value={inverted ? distance * 1.609 : distance}
              id="Km"
              placeholder="Km"
              type="number"
              onChange={onChange}
              disabled={inverted}
            />
          </div>
          <div>
            <label htmlFor="Miles">Miles</label>
            <input
              value={inverted ? distance : distance / 1.609}
              id="Miles"
              placeholder="Miles"
              type="number"
              onChange={onChange}
              disabled={!inverted}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={OnInvert}>
            {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 your units</option>
            <option value="0">Minutes & Hours</option>
            <option value="1">Km & miles</option>
          </select>
          <hr />
          {index === "xx" ? "Please select your units" : null}
          {index === "0" ? <MinutesToHours /> : null}
          {index === "1" ? <KmToMiles /> : null}
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

3. React Js (Props, Memorized)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
  <!-- 운영모드 React : React JS 엔진 역할-->
  <!-- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->
  <!-- 운영모드 React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <!--개발모드 React -->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!--개발모드 React-dom-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    function Btn({ text, changeValue }) {
      //Btn(props) : 파라미터로 전달받는 properties를 의미. props 대신 shorcut으로 사용하는게 간편하다.
      /* 
      아래 둘은 같은 기능이다 
      Btn(props)로 선언 시 {props.text}로 사용
      Btn({text})로 선언 시 {text}로 사용 
      */
      return (
        <button
          onClick={changeValue}
          style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
          }}
        >
          {text}
        </button>
      );
    }
    const MemorizedBtn = React.memo(Btn); //React Js의 memorized 기능을 사용해서 state에 따라 변하지 않는 엘리멘트는 불필요한 렌더링 방지를 위해 memorized 사용(props가 변할때만 렌더링)
    function App() {
      const [value, setValue] = React.useState("Save Changes");
      const changeValue = () => setValue("Revert Changes");
      return (
        <div>
          <MemorizedBtn text={value} changeValue={changeValue} />
          <MemorizedBtn text="Continue" />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

4. React Js (Props, propTypes 사용법)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
  <!-- 운영모드 React : React JS 엔진 역할-->
  <!-- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->
  <!-- 운영모드 React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <!--개발모드 React -->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!--개발모드 React-dom-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
  <!-- props로 넘어오는 속성의 타입을 지정 후 틀릴 값 전달 시 확인 가능하다 -->
  <script type="text/babel">
    function Btn({ text, fontSize }) {
      return (
        <button
          style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
            fontSize,
          }}
        >
          {text}
        </button>
      );
    }
    Btn.propTypes = {
      text: PropTypes.string.isRequired, //isRequired : 해당 prop은 필수 값을 의미
      fontSize: PropTypes.number,
    };
    function App() {
      return (
        <div>
          <Btn text="Save Changes" fontSize={18} />
          <Btn text={"Continue"} />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

 

 

[Nomad] ReactJS로 영화 웹 서비스 만들기 1

웹/React.js 2024. 1. 1. 18:59

노마드코더 강의 1일차.

심심해서 만들어보는 React JS 강의 수강

 - ReactJS로 영화 웹 서비스 만들기

  1. 준비물

     > 바닐라 JS에 대한 기초 지식, Visual Studio Code

     > 바닐라 JS 기초 강의 참고(무료)

     > React JS : https://unpkg.com/react@18/umd/react.production.min.js

     > React-Dom : https://unpkg.com/react-dom@18/umd/react-dom.production.min.js

     > Babel : https://unpkg.com/@babel/standalone/babel.min.js

 

Jsx format로 자동 변환
1. Vscode > Prettier - Code formatter 설치
2. Ctrl + P > User settings
3. Default formatter 검색
4. 없음 -> Prettier - Code formatter 변경
5. Format on Save 검색
6. 체크
7. Ctrl + S 로 저장 시 자동으로 구조변환됨

  

* Vanilla Js vs React Js 코드 비교

1. Vanilla JS
<!DOCTYPE html>
<html>
    <body>
        <span>Total Clicks: 0</span>
        <button id="btn">Click me!</button>
    </body>
    <script>
        let counter = 0;
        const button = document.getElementById("btn");
        const span = document.querySelector("span");
        function handleClick() {
            counter += 1;
            span.innerHTML = 'Total Clicks: '+counter;
        }
        button.addEventListener("click", handleClick)
    </script>
</html>

 

2. React Js
<!DOCTYPE html>
<html>
    <body>
        <div id="root"></div>
    </body>
    <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>      <!--React : React JS 엔진 역할-->
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <!--React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
    <script>
        const root = document.getElementById("root");
        const h3 = React.createElement(
            "h3",
            {
                id: "title",
                onMouseEnter: () => console.log("mouse enter"),
            },
            "Hello I'm a span"
        );       //span element 생성
        const btn = React.createElement(
            "button",
            {
                onClick: () => console.log("I'm clicked"),
                style: {
                    backgroundColor: "tomato",
                }
            },
            "Click me"
        );
        const container = React.createElement("div", null, [h3, btn]);
        ReactDOM.render(container, root);
    </script>
</html>

 

 - React JS가 좋은 점은 addEvenetListener를 각각 선언할 필요가 없이, 각 요소별로 기재하면 됨

 

3. React Js (JSX, Babel 사용)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <!--React : React JS 엔진 역할-->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <!--React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    const root = document.getElementById("root");
    /* 1. React 방식
        const h3 = React.createElement(
            "h3",
            {
                id: "title",
                onMouseEnter: () => console.log("mouse enter"),
            },
            "Hello I'm a span"
        );       //span element 생성 
        */
    // 2. JSX 방식 (JavaScript Extension. HTML 문법과 흡사하기 때문에 React 방식보다 익숙함)
    const Title = (
      <h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
        Hello I'm a span
      </h3>
    );
    /* 
        const btn = React.createElement(
            "button",
            {
                onClick: () => console.log("I'm clicked"),
                style: {
                    backgroundColor: "tomato",
                }
            },
            "Click me"
        );
        */
    const Button = (
      <button
        style={{
          backgroundColor: "tomato",
        }}
        onClick={() => console.log("I'm clicked")}
      >
        "Click me"
      </button>
    );
    const container = React.createElement("div", null, [Title, Button]);
    ReactDOM.render(container, root);
  </script>
</html>

 

4. React Js (렌더링 할 때에도 JSX 형태로 사용)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <!--React : React JS 엔진 역할-->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <!--React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    const root = document.getElementById("root");
    const Title = () => (
      //arrow function
      <h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
        Hello I'm a span
      </h3>
    );
    const Button = () => (
      <button
        style={{
          backgroundColor: "tomato",
        }}
        onClick={() => console.log("I'm clicked")}
      >
        Click me
      </button>
    );
    //Component는 반드시 대문자로 시작해야함(사용자 정의 tag가 됨)
    const Container = () => (
      <div>
        <Title />
        <Button />
      </div>
    );
    ReactDOM.render(<Container />, root);
  </script>
</html>

 

5. React Js (변경 시 마다 Render 하도록 추가. 좋은 소스는 아님)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <!--React : React JS 엔진 역할-->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <!--React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp() {
      counter += 1;
      render();
    }
    function render() {
      ReactDOM.render(<Container />, root);
    }
    function Container() {
      return (
        <div>
          <h3>Total Clicks: {counter}</h3>
          <button onClick={countUp}>Click me</button>
        </div>
      );
    }
    render();
  </script>
</html>

 

6. React Js (userState를 사용해서 ReRednering 까지 modifier로 수행하도록 처리)
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <!--React : React JS 엔진 역할-->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  <!--React-dom : 생성된 React 요소를 HTML에 배치하는 역할-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- JSX 인식을 위한 Babel -->
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => {
        //   setCounter(counter + 1); //값을 바꾸고 리렌더링함
        setCounter((current) => current + 1); //counter+1과 동일한 결과를 출력하지만 current가 확실히 현재 값이라는 것을 보장할 수 있다 (다른 값에 의해 counter가 변경될 수 있기 때문)
      };
      return (
        <div>
          <h3>Total Clicks: {counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>