본문 바로가기

React

React(3) - Counter 구현, React 주요 개념 복습 및 comment(댓글) 구현 복습

728x90
반응형

1) React

   1-1) Counter

   1-2) React 주요 개념 복습 및 comment(댓글) 구현 복습

 

 

 

 

 

 

1) React

1-1) Counter

React를 이용하여 만들 때 꼭 만드는 것 중 하나가 "Counter"이다!
Counter : "+" 버튼을 누르면 1씩 증가하고, "-" 버튼을 누르면 1씩 감소하게 하는 것

 

 

counter.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/babel">
      class Counter extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            number: 0,
          };

          this.increment = this.increment.bind(this);
          this.decrement = this.decrement.bind(this);
        }

        // componentDidMount(생명주기) 함수를 통해 기존의 state 값(number: 0)을 새로운 값(number: 10)으로 변경한 뒤 render를 다시 하도록 하는 코드
        componentDidMount() {
          // this.setState({ number: 10 });

          window.setTimeout(() => {
            this.setState({ number: 10 });
          }, 3000);
        }

        // state(상태)가 바뀔 때마다 componentDidUpdate 메서드가 호출됨!!
        componentDidUpdate() {
          console.log(this.state.number);
        }

        increment() {
          this.setState({ number: this.state.number + 1 });
        }

        decrement() {
          this.setState({ number: this.state.number - 1 });
        }

        render() {
          return (
            <div>
              <h2>{this.state.number === 0 ? "로딩중" : this.state.number}</h2>
              <button onClick={this.increment}>+</button>
              <button onClick={this.decrement}>-</button>
            </div>
          );
        }
      }

      class App extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <Counter />
            </div>
          );
        }
      }

      const root = ReactDOM.createRoot(document.querySelector("#root"));
      root.render(<App />);
    </script>
  </body>
</html>

 

 

counter2.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/babel">
      class Counter extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            number: 0,
            Loading: true,
          };

          this.increment = this.increment.bind(this);
          this.decrement = this.decrement.bind(this);
          this.setLoading = this.setLoading.bind(this);
        }

        // componentDidMount(생명주기) 함수를 통해 기존의 state 값(number: 0)을 새로운 값(number: 10)으로 변경한 뒤 render를 다시 하도록 하는 코드
        componentDidMount() {
          // this.setState({ number: 10 });

          window.setTimeout(() => {
            this.setState({ number: 10, Loading: false });
          }, 3000);
        }

        // state(상태)가 바뀔 때마다 componentDidUpdate 메서드가 호출됨!!
        componentDidUpdate() {
          console.log(this.state.number);
          if (this.state.Loading === true) {
            this.increment();
          }
        }

        setLoading() {
          this.setState({ Loading: true });
        }

        increment() {
          this.setState({ number: this.state.number + 1, Loading: false });
        }

        decrement() {
          this.setState({ number: this.state.number - 1 });
        }

        render() {
          if (this.state.Loading) return <div>로딩~~</div>;
          return (
            <div>
              <h2>{this.state.number}</h2>
              <button onClick={this.setLoading}>+</button>
              <button onClick={this.setLoading}>-</button>
            </div>
          );
        }
      }

      class App extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <Counter />
            </div>
          );
        }
      }

      const root = ReactDOM.createRoot(document.querySelector("#root"));
      root.render(<App />);
    </script>
  </body>
</html>

 

 

 

 

1-2) React 주요 개념 복습 및 comment(댓글) 구현 복습

주요 개념

  • JSX : JSX 문법은 "{}(중괄호)"를 사용해야 한다는 점을 기억할 것!!
  • Component : Component는 "Element의 모음"을 의미하며, 단 하나의 상태만을 가질 수 있고, 상태에 따라 Element가 바뀜!
  • Props : Props는 데이터(값)를 전달하는 역할만 하며, 방향은 항상 자식 Component에게만 향함!
  • State : State(상태)는 Element에 표현할 데이터를 모아주는 변수임!
  • 생명주기 : 생명주기는 상태 변화에 따른 실행할 추상 메서드들을 말함  -->  ex) "this.setState()"를 사용할 경우, "componentDidUpdate"와 "render" 메서드가 실행되는 상황
  • 이벤트 : 이벤트를 등록하는 방법에 대해서만 정확히 인지하면 되며, 이벤트는 JSX 문법 안에서 작성한다는 것인데 class, Component 같은 경우에는 this binding을 알면 좋긴함!
  • 조건부 rendering : 이는 "JSX 문법"과 "삼항 연산자"를 제대로 이해하는 것이 중요하며, 그에 따른 Component 호출에 대한 것을 이해해야 함!
  • list : 같은 Element를 여러 번 사용할 시, 이를 "배열"에 담아서 사용해도 출력된다는 사실을 기억해야 하며, Element의 형태는 같지만 안의 데이터가 다를 경우에는 해당 데이터를 가지고 map 메서드를 사용하여 배열 내용을 변경할 줄 알면 됨!
  • form : 이벤트와 state를 이해하는 것이 중요함(단, form element에서 submit 이벤트가 어떻게 돌아가는지 이해하는 것이 중요하며, 추가로 새로고침하면 state가 리셋된다는 사실을 인지하고 이를 방지하기 위해 "e.preventDefault()"를 호출한다는 점을 기억할 것!!)
  • state 끌어올리기 : (1) 부모 component와 자식 component를 구별할 줄 알아야 하며, function(함수)이 값이라는 사실을 알아야 함  /  (2) 상태는 component마다 있는 것이며, state 끌어올리기는 React에서 구현해준 것이 아니라 Javascript의 기초적인 개념을 복합적으로 사용해서 된다라는 사실을 인지하고 있어야 함!  /  (3) state 끌어올리기 원리 : 부모 Component에서 본인의 state를 바꾸는 함수를 구현한 뒤 해당 함수를 자식 Component에게 Props로 전달함. 이후 자식 Component는 부모 Component로부터 받은 함수를 실행함.

 

comment.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/babel">
      class C extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return <div>Props: {this.props.text}</div>;
        }
      }

      class B extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <C text={this.props.id} />
            </div>
          );
        }
      }

      class A extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <B id={this.props.name} />
            </div>
          );
        }
      }

      class Props extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <A name="web7722" />
            </div>
          );
        }
      }

      class Form extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            value: "",
            word: "",
          };

          this.handleChange = this.handleChange.bind(this);
          this.handleSubmit = this.handleSubmit.bind(this);
        }

        // "onChange"는 한 글자씩 쓸 때마다 쓴 값이 반영된다!
        handleChange(e) {
          // console.log(e.target.value);
          this.setState({ value: e.target.value });
        }

        handleSubmit(e) {
          e.preventDefault(); // form 태그의 기본적인 특성인 이동하는 특성(action 속성값에 따라 이동함)을 막고 시작해야 함! --> 페이지를 이동하여 다시 화면을 render하게 되는 순간 기존 값들이 날라가기 때문!!
          this.setState({
            word: this.state.value,
            value: "",
          });
        }

        render() {
          return (
            <form onSubmit={this.handleSubmit}>
              <input
                type="text"
                onChange={this.handleChange}
                value={this.state.value}
              />
              <button type="submit">전송</button>
              <div>{this.state.word}</div>
            </form>
          );
        }
      }

      class List extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            board: [
              { id: 1, subject: "asdf7722" },
              { id: 2, subject: "qwer7722" },
              { id: 3, subject: "vbnm7722" },
              { id: 4, subject: "ghjk7722" },
            ],
          };
        }

        getList(board) {
          return board.map((v) => <li key={v.id}>{v.subject}</li>);
        }

        render() {
          return <ul>{this.getList(this.state.board)}</ul>;
        }
      }

      class Counter extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            number: 0,
            Loading: true,
          };

          this.increment = this.increment.bind(this);
          this.decrement = this.decrement.bind(this);
          this.setLoading = this.setLoading.bind(this);
        }

        // componentDidMount(생명주기) 함수를 통해 기존의 state 값(number: 0)을 새로운 값(number: 10)으로 변경한 뒤 render를 다시 하도록 하는 코드
        componentDidMount() {
          // this.setState({ number: 10 });

          window.setTimeout(() => {
            this.setState({ number: 10, Loading: false });
          }, 3000);
        }

        // state(상태)가 바뀔 때마다 componentDidUpdate 메서드가 호출됨!!
        componentDidUpdate() {
          console.log(this.state.number);
          if (this.state.Loading === true) {
            // this.increment();
            window.setTimeout(this.increment, 1000);
          }
        }

        setLoading() {
          this.setState({ Loading: true });
        }

        increment() {
          this.setState({ number: this.state.number + 1, Loading: false });
        }

        decrement() {
          this.setState({ number: this.state.number - 1 });
        }

        render() {
          if (this.state.Loading) return <div>로딩~~</div>;
          return (
            <div>
              <h2>{this.state.number}</h2>
              <button onClick={this.setLoading}>+</button>
              <button onClick={this.setLoading}>-</button>
            </div>
          );
        }
      }

      class App extends React.Component {
        constructor(props) {
          super(props);
        }

        render() {
          return (
            <div>
              <Counter />
              <Form />
              <List />
              <Props />
            </div>
          );
        }
      }

      const root = ReactDOM.createRoot(document.querySelector("#root"));
      root.render(<App />);
    </script>
  </body>
</html>