Gom3rye

Who Am I] Components와 Props / State 다루기 본문

웹 개발

Who Am I] Components와 Props / State 다루기

Gom3rye 2022. 9. 1. 17:45

컴포넌트 형으로 Hello compoenent! 출력하기

<!DOCTYPE html>
<html lang="en">
  <body>
    <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>   // react를 가져오기 위한 코드
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>   // 바벨 스크립트 넣어주기
    
    <div id="root"></div>
    <script type="text/babel">   // type="text/babel"을 넣어주어야 jsx 사용 가능
      const rootElement = document.getElementById("root");  // id가 root인 element 가져와서 rootElement로 선언
      
      function Hello({name}){   // 객체 배열 안에 있는 name이 들어오게 되므로 {props.name}말고 {name}만 적어도 된다.
        return <h1>Hello, {name}!</h1>;
      }
      // const Hello = (props) => { <h1>Hello, {props.name}!</h1>; } 위 코드와 동일하게 작동함
      
      const element = <Hello name="component" />;
      
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

Componenet를 사용하면 좋은 점 실습

<!DOCTYPE html>
<html lang="en">
  <body>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");

      function Button({number}) {
        return (
          <button 
          style={(backgroundColor :number? %2 ===0 "pink": "green")
            }>{number}</button>
          );
      } // button이라는 단일 버튼을 형성하는 컴포넌트 만들어주기

      const Buttons = () => {
      <>
      <button>1</button>
      <button>2</button>
      <button>3</button>
      <Button number={4} />
      <Button number={5} />
      <Button number={6} />
      </>
      };

      ReactDOM.render(Buttons(), rootElement);   // button컴포넌트는 함수형 컴포넌트이므로 ()붙여준다.
    </script>
  </body>
</html>

- Button 컴포넌트를 사용하면 일일이 태그에 style={} 넣어주지 않아도 간결하게 한 번에 스타일 적용 가능하다.

=> 코드의 재사용성을 높여주었다.

State란?

리액트에서는 state 값의 불변성이라는 개념이 아주 중요하게 등장한다.

- 불변성은 어떤 값을 직접 변경하지 않고 새로운 값을 만들어 내는 것을 의미한다.

 

리액트에서 컴포넌트가 update된 값을 반영하는 방법을 보면

1. props 전달받음

2. 그 값을 바탕으로 shouldComponentUpdate 함수를 실행해서 false면 멈추고 true를 리턴하면 다음 단계로 이동한다.

3. 가상 돔과 실제 돔을 비교해서 업데이트 된 해당 부분을 랜더링 해준다.

 

여기서 특정 컴포넌트가 update할 필요가 없다는 것을 어떻게 판단할 수 있을까?

가장 간단한 방법은 컴포넌트가 가지고 있는 이전 값들을(props, state 등) 완전히 비교하는 것이다.

Ex) 기존 {key: 1, name: "이름"}  ->  전달 {key: 1, name: "나이"}

 

만약 불변성이 지켜지지 않은 채로 기존의 값이 변경된다면 

기존 {key: 1, name: "이름"}  ->  기존 {key: 1, name: "나이"}  ->  전달 {key: 1, name: "나이"}

이렇게 객체의 내부의 값이 새로워졌지만 react는 기존 객체와 전달 객체가 같은 것으로 판단하기 때문에 바뀐 것을 감지하지 못하는 대참사가 일어날 수 있다.

===> 따라서 react에서는 불변성을 반드시 지켜서 state 관리를 해줘야 한다.

<!DOCTYPE html>
<html lang="en">
  <body>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      
      const state = {name:"button", color:"pink"}; // 배열 객체

      function Button({number}) {
        return (
          <button 
          style={{backgroundColor :number? %2 ===0 "pink": "green"}}>
          {number}
          </button>
          );
      } // button이라는 단일 버튼을 형성하는 컴포넌트 만들어주기

      const Buttons = () => {
      <>
      <button style={{backgroundColor: state.color}}>{state.color + state.name}</button>  //pinkbutton 이라는 글씨가 들어간 버튼이 생성된다.
      </>
      };

      ReactDOM.render(Buttons(), rootElement);   // button컴포넌트는 함수형 컴포넌트이므로 ()붙여준다.
    </script>
  </body>
</html>

- props로 pinkbutton 생성하기

<!DOCTYPE html>
<html lang="en">
  <body>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      
      const state = {name:"button", color:"pink"}; // 배열 객체

      function Button({props}) {  //객체니까 {}넣어주기
        return (
          <button 
          style={{backgroundColor :props.color}}>
          {props.color}
          {props.name}
          </button>
          );
      } // button이라는 단일 버튼을 형성하는 컴포넌트 만들어주기
      
      const Buttons = () => {
      <>
      <button style={{backgroundColor: state.color}}>{state.color + state.name}</button>  //pinkbutton 이라는 글씨가 들어간 버튼이 생성된다.
      <Button props={state} />  //props는 state 객체를 넘겨줌
      </>
      };

      ReactDOM.render(Buttons(), rootElement);   // button컴포넌트는 함수형 컴포넌트이므로 ()붙여준다.
    </script>
  </body>
</html>

- name과 color 선언해서 미리 주기

<!DOCTYPE html>
<html lang="en">
  <body>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      
      const state = {name:"button", color:"pink"}; // 배열 객체

      function Button({name , color}) {  //객체니까 {}넣어주기
        return (
          <button 
          style={{backgroundColor :color}}>
          {color}
          {name}
          </button>
          );
      } // button이라는 단일 버튼을 형성하는 컴포넌트 만들어주기
      
      const Buttons = () => {
      <>
      <button style={{backgroundColor: state.color}}>{state.color + state.name}</button>  //pinkbutton 이라는 글씨가 들어간 버튼이 생성된다.
      <Button name={state.name} color={state.color} />  //props는 state 객체를 넘겨줌
      </>
      };

      ReactDOM.render(Buttons(), rootElement);   // button컴포넌트는 함수형 컴포넌트이므로 ()붙여준다.
    </script>
  </body>
</html>

- useState를 사용하면 좀 더 편하게 state를 관리할 수 있다.

<!DOCTYPE html>
<html lang="en">
  <body>
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      
      const state = {name:"button", color:"pink"}; // 배열 객체

      function Button() {  //객체니까 {}넣어주기
        const [color, setColor] = React.useState("green");
        const [name, setName] = React.useState("button");
        
        return (
          <button 
          style={{backgroundColor :color}}>
          {color}
          {name}
          </button>
          );
      } // button이라는 단일 버튼을 형성하는 컴포넌트 만들어주기
      
      const Buttons = () => {
      <>
      <button style={{backgroundColor: state.color}}>{state.color + state.name}</button>  //pinkbutton 이라는 글씨가 들어간 버튼이 생성된다.
      <Button /> 
      </>
      };

      ReactDOM.render(Buttons(), rootElement);   // button컴포넌트는 함수형 컴포넌트이므로 ()붙여준다.
    </script>
  </body>
</html>

-> <Button />에 props를 전달해주지 않았음에도 불구하고 버튼이라는 컴포넌트 안에서( -> function Button() {} ) 새롭게 state를 useState라는 함수를 통해서 선언해주었기 때문에 정상적으로 pinkbutton 버튼과 greenbutton 버튼이 나오는 것을 확인할 수 있다.

- 즉, state는 함수 밖에서(컴포넌트 밖에서) 전역 변수로 선언이 가능하고 함수 안에서 React.useState를 통해 state 사용이 가능하다.

728x90
반응형