관리 메뉴

공부기록용

ReactJS로 영화 웹 서비스 만들기(03_2/state활용) 본문

📚강의록📚/노마드)React

ReactJS로 영화 웹 서비스 만들기(03_2/state활용)

과부하가즈아 2023. 7. 12. 19:50

https://nomadcoders.co/react-for-beginners/lobby

 

ReactJS로 영화 웹 서비스 만들기 – 노마드 코더 Nomad Coders

왕초보를 위한 React

nomadcoders.co


JSX는 HTML과 비슷하지만 몇 가지 다른 점이 있다. 

💫
class → className

class는 html에서 style값을 작성할 때 쓰이는 옵션으로, 원래는 html에서 class = "name"으로 태그 안에 넣는다. 하지만 React에서는 className으로 넣어서 class를 사용한다. 이렇게 쓰이는 이유는 React에서는 class함수, 화살표 함수 두 가지 방식으로 코드를 작성하기 때문에 class가 아닌 className으로 명칭을 사용한다. 
<div class = "container"></div>
▼
<div className = "container"></div>​


for → htmlFor
html에서는 label과 input을 연결해야 할 때, label에서는 for값, input에서는 id값을 통해 둘이 같다는 의미를 표시했다. 하지만 React에서는 for대신 forName을 써야한다. React에서는 for는 for문을 의미하기 때문에 htmlFor이라는 값으로 변경을 해야한다. 
<label for = "a"></label>
<input id = "a"/ >
▼
<label htmlfor = "a"></label>
<input id = "a"/ >​

만들고자 하는 것
분을 숫자로 입력하는 창 -> 시간으로 환산되어 시간 입력 창에 나타남(이때 시간 입력창은 비활성)
시간을 숫자로 입력하는 창 -> 분으로 환산되어 분 입력 창에 나타남(이때 분 입력창은 비활성)

버튼 2가지
1. flip 버튼
: 분에서 시간으로 환산, 시간에서 분으로 환산시 입력 창 외 환산되어 보여지는 창을 비활성화 시키도록 바꿔주는 기능
input의 disabled 속성을 사용(true이면 비활성, false이면 활성) 초기 값을 false로 하여 활성화 시킴
-> 분의 입력창을 flip의 버튼의 클릭으로 분과 시간의 disabled값을 변화 시키고자 함

2. reset 버튼 : 모든 입력창의 숫자가 초기화 됨

분과 시간을 입력하는 input 생성

<!DOCTYPE html>

<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- import -->

  <!-- React -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <!-- ReactDOM  -->
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">
    const root = document.getElementById("root");

    function App() {
      
      return (
        <div>
          <!-- className -->
          <h1 className="hi">Super Converter</h1>
          
          <!-- htmlFor -->
          <label htmlFor="minutes">Minutes</label>
          <input id="minutes" placeholder="Minutes" type="number"/>

          <label htmlFor="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number"/>
          
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

CDN

<!-- React -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <!-- ReactDOM  -->
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

"리엑트에서 input는uncontrolled다. "

💫react uncontrolled input
제어되는 컴포넌트란 무엇이고 제어되지 않는 컴포넌트란 무엇인가? 

controlled
제어된다는 것은 폼의 상태 또는 값이 컴포넌트의 상태를 통해 관리된다는 것을 말한다. 이 경우, 우리는 input의 value prop을 컴포넌트에서 관리하는 상태값으로 세팅하게 된다. 또한 해당 상태값을 onChange 이벤트 핸들러로 업데이트할 수 있다. 따라서 input의 값과 업데이트를 React 컴포넌트 자체에서 관리할 수 있게 된다.

사실 React 컴포넌트를 만들어 본 적이 있다면 이는 당연한 내용처럼 보인다. 컴포넌트에서 변경 가능한 state를 관리하는 것은 매우 자연스러운 설계다. 그러나 후술할 “제어되지 않는 컴포넌트"의 반대되는 개념인 “제어되는 컴포넌트"가 등장하는 이유는, HTML의 form 요소는 다른 엘리먼트들과는 조금 다르게 동작하기 때문이다.

<input>, <textarea>, <select> 같은 form 요소들은 자체적으로 내부 상태를 가지고, 유저 입력에 따라 업데이트된다. 즉, input 엘리먼트 자체가 스스로 state를 가지고, 유저 입력에 따라 해당 상태가 업데이트 된다는 것이다.


uncontrolled
제어되지 않는다는 것은 폼의 상태 또는 값이 React가 아닌 DOM에서 처리된다는 것을 말한다. 이 말은 자바스크립트로 쓰여진 리액트 코드로 input의 상태값을 관리하는 것이 아닌, DOM 자체에서 상태를 관리한다는 말로 이해해볼 수 있다. 이 경우, 우리는 input의 value prop으로 값을 세팅하지 않는다.

https://jihyundev.tistory.com/23

분과 시간을 입력하여 UI에 나타내고자 함_입력 즉시 값을 알아내고자 함

<!DOCTYPE html>

<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- import -->

  <!-- React -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <!-- ReactDOM  -->
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">
    const root = document.getElementById("root");

    function App() {

      const[minutes, setMinutes]=React.useState()

      // const함수만들기 = () => {}
      const onChange = () => {
        console.log("somebody wrote")
      }

      return (
        <div>
          <h1 className="hi">Super Converter</h1>
          
          <label htmlFor="minutes">Minutes</label>
          <input 
          value={minutes}
          id="minutes"
          placeholder="Minutes" 
          type="number"
          onChange={onChange}/>

          <label htmlFor="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number"/>
          
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

<input 
  value={minutes}
  id="minutes"
  placeholder="Minutes" 
  type="number"
  onChange={onChange}
/>

> input값을 value연결시켜주는 이유는 input값을 외부에서도 수정해주기 위함

const[minutes, setMinutes]=React.useState()

// const함수만들기 = () => {}
const onChange = () => {
  console.log("somebody wrote")
}


분과 시간을 입력하여 UI에 나타내고자 함_event접근해서 입력하는 값을 알아내어 분에 입력하는 숫자를 시간에도 출력

const onChange = (event) => {
  console.log(event)
}


const onChange = (event) => {
  console.log(event.target)
}


const onChange = (event) => {
  console.log(event.target.value)
}


<!DOCTYPE html>

<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- import -->

  <!-- React -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <!-- ReactDOM  -->
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">
    const root = document.getElementById("root");

    function App() {

      const[minutes, setMinutes]=React.useState()

      // const함수만들기 = () => {}
      const onChange = (event) => {
        // 바로 minutes를 만들어 준게 됨
        setMinutes(event.target.value)
      
      }

      return (
        <div>
          <h1 className="hi">Super Converter</h1>

          <label htmlFor="minutes">Minutes</label>
          <input 
          value={minutes}
          id="minutes"
          placeholder="Minutes" 
          type="number"
          onChange={onChange}/>
          <h4>You want to convert {minutes}</h4>

          <label htmlFor="hours">Hours</label>
          <input id="hours" placeholder="Hours" type="number"/>
          
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>
const onChange = (event) => {
  setMinutes(event.target.value)
}
<h4>You want to convert {minutes}</h4>


분과 시간을 입력하여 UI에 나타내고자 함_시간의 입력 창에 분에 입력한 값이 나오도록 함

return (
  <div>
    <h1 className="hi">Super Converter</h1>

    <div>
      <label htmlFor="minutes">Minutes</label>
      <input
        value={minutes}
        id="minutes"
        placeholder="Minutes"
        type="number"
        onChange={onChange} />
    </div>

    <div>
      <label htmlFor="hours">Hours</label>
      <input
       id="hours"
       placeholder="Hours"
       type="number"
       value={minutes} />
    </div>
    
  </div>
);

hours의 value만 분의 60으로 나누어 준다.

value={ minutes / 60 }


const[minutes, setMinutes]=React.useState()

> state를 60으로 나누어서 보여주고 있다.

const onChange = (event) => {
  setMinutes(event.target.value)
}

> 여기에서 state를 바꿔주고 있고 그렇게 새로 업데이트된 값을 가지고 return의 해당 state 코드가 다시 한 번 렌더링 되는 것이다. 


값을 없애주는 reset버튼, 기능 추가

<button onClick={reset}>Reset</button>

> 버튼

const reset = () => {
  setMinutes(0);
}

> 기능, 함수추가

> state에 연결된 모든 것들을 전부 0으로 돌아가게 된다. 


분에서 시간으로, 시간에서 분으로 환산시  환산되어 보여지는 창을 비활성화 시키도록 바꿔주는 기능

 

input의 disabled 속성을 사용(true이면 비활성, false이면 활성) 초기 값을 false로 하여 활성화 시킴
-> 분의 입력창을 flip의 버튼의 클릭으로 분과 시간의 disabled값을 변화 시키고자 함

💫disabled 속성

<input> 태그의 disabled 속성은 해당 <input> 요소가 비활성화됨을 명시한다.

disabled 속성은 불리언(boolean) 속성으로 해당 속성을 명시하지 않으면 속성값이 자동으로 false(활성화) 값을 가지게 되며, 명시하면 자동으로 true(비활성화) 값을 가지게 된다.

disabled 값이 true이면 버튼이 비활성화 되고, false이면 활성화 된다.

또한, 폼 데이터가 제출될 때도 disabled 속성이 명시된 <input> 요소의 데이터는 제출되지 않는다.

<!DOCTYPE html>

<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- import -->

  <!-- React -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <!-- ReactDOM  -->
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">
    const root = document.getElementById("root");

    function App() {
      const [minutes, setMinutes] = React.useState();

      const [flipped, setFlipped] = React.useState(false);

      const onChange = (event) => {
        setMinutes(event.target.value);
      };

      const reset = () => {
        setMinutes(0);
      };

      //const FlipClick  = () => {setFlipped((currnet) => {!currnet})};
      const FlipClick  = () => setFlipped((current) => !current);

      return (
        <div>
          <h1 className="hi">Super Converter</h1>

          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={minutes}
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              disabled={flipped === true}
            />
          </div>

          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={Math.round(minutes / 60)}
              id="hours"
              placeholder="Hours"
              type="number"
              disabled={flipped === false} // disabled속성: 값이 true이면 비활성화, false이면 활성화 그래서 state값으로 활성화할지 비활성화할지 결정할 수 있다.
            />
          </div>

          <button onClick={reset}>Reset</button>
          <button onClick={FlipClick }>Flip</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

> Hours 단위 변환을 뒤집는 함수 생성

const FlipClick  = () => setFlipped((current) => !current);

 

> flipped의 기본 상태가 false이고 UI에서 만들어 둔 Flip button에서 onClick가 발생하면 항상 그 시점의 flipped의 상태와는 반대로 값을 바꿔주자는 의미
const[flipped, setFlipped] = React.useState(false)

 

<input
  value={Math.round(minutes / 60)}
  id="hours"
  placeholder="Hours"
  type="number"
  disabled={flipped === false} // disabled속성: 값이 true이면 비활성화, false이면 활성화 그래서 state값으로 활성화할지 비활성화할지 결정할 수 있다.
/>

> flipped의 기본 값은 false이다. (flipped가 false이면 Hours는 disabled가 되어야 함)
> disabled={flipped === false}를 써줘서 flipped가 false라면, disabled는 true가 되도록 만들어 준다. 
(flipped === false의 식으로 flipped가 false라면, 식은 ture가 되고 결국 disabled= {true}가 되고 그럼 결국 비활성화가 되는 것을 의미)

> 즉, state값(flipped)으로 input을 enabled할지 disabled 할지를 결정할 수 있다는 의미이다. 


Minutes 변환을 위한 생성

<input
  value={minutes}
  id="minutes"
  placeholder="Minutes"
  type="number"
  onChange={onChange}
  disabled={flipped === true}
/>

disabled={flipped === true}로 flip버튼을 누른다면 hours를 사용하겠다는 의미로 minute를 비활성화 하겠다는 의미


시간 입력창에도 숫자를 넣으면 분에 환산되어 보여지게 하기

 

분과 시간의 value에 각각의 단위에 맞게 환산되도록 식이 있음을 주의

<input
  value={flipped ? minutes : Math.round(minutes / 60)} 
  id="hours"
  placeholder="Hours"
  type="number"
  disabled={flipped === false} // disabled속성: 값이 true이면 비활성화, false이면 활성화 그래서 state값으로 활성화할지 비활성화할지 결정할 수 있다.
  onChange={onChange}
/>


value={flipped ? minutes : Math.round(minutes / 60)}

> flipped가 true면

> Hours의 disabled가 false로 활성화, minutes을 보여주고

> false라면

> Hours의 disabled가 true로 비활성화, 시간으로 환산해서 보여주기


💫💫맨 초기의 상태는 

const [flipped, setFlipped] = React.useState(false);
// Minutes
disabled={flipped === true}

// Hours
disabled={flipped === false}

로써 flipped가 false, minutes를 60이라고 하면

Minutes가 false로 활성화, Hours가 true로 비활성화 상태

 

// Minutes
value={flipped ? minutes*60 : minutes} 

// Hours
value={flipped ? minutes : Math.round(minutes / 60)}

flipped가 false로

Minutes가 minutes값(60) 그대로 출력, Hours가 Math.round(minutes / 60)로 시간으로 환산되어 출력(1)

 

Flip버튼 클릭으로 FlipClick 함수가 작동되면 flipped의 값은 

const FlipClick  = () => setFlipped((current) => !current);

(current) => !current 으로 인해 false -> true가 된다 그럼 


// Minutes
disabled={flipped === true}

// Hours
disabled={flipped === false}

flipped가 true로

Minutes가 true로 비활성화, Hours가 false로 활성화 상태

 

// Minutes
value={flipped ? minutes*60 : minutes} 

// Hours
value={flipped ? minutes : Math.round(minutes / 60)}

flipped가 true로

Minutes는 minutes*60 출력(60*60=3600), Hours는 minutes(60)를 출력되는 것이다. 


근데 이제 minutes의 값이(60) 옮겨져서 환산되는게 이상하니까 그냥 Flip버튼 클릭시 활성이 바뀌면서 리셋도 같이 해주기로함

const FlipClick  = () => {
  setFlipped((current) => !current);
  reset();
};

 

Comments