[ React ] #5

부리또의 댄스·2024년 2월 6일
0

React

목록 보기
5/6
post-thumbnail

✣ 생활코딩(인프런) - React ✣


Section 5: Create 기능 구현

5-1) 베이스 캠프

propsstate의 차이점?

props는 부모 컴포넌트로부터 읽을 수만 있는 것이고, 웹 사이트의 사용자가 수정할 수 없다.

반면 state는 웹 사이트와 사용자간의 상호작용을 통해 수정될 수 있는, 일종의 '버튼'이다. this.setState를 통해 상태를 변경할 수 있다.

하지만 공통점은, 두 개 모두 상태가 변경되면 render() 함수가 재호출된다는 것이다.


사진처럼 컴포넌트들이 위아래로 연결되어 있을 때,

상위 컴포넌트에서 하위 컴포넌트에게 명령을 할 때(값을 전달할 때)는 props를 통해서 전달하고,

하위 컴포넌트에서 상위 컴포넌트에게 명령을 할 때는 event를 통해서, 즉 state를 변경함으로서 수행한다.

(사진에서 의미하는 것은 Redux를 사용하면 이러한 변경 과정이 하나하나의 컴포넌트를 모두 거치지 않고 한 번에 가능하게 할 수 있다는 것이다.)

5-2) create 구현 : 소개


지금까지 만들어놓았던 것에서, 'create', 'update', 그리고 'delete' 기능을 추가해볼 것이다.

props, state, 그리고 event를 활용한다.

5-3) create 구현 : mode 변경 기능

< Control.js >

import React, { Component } from 'react';

class Control extends Component {
    render() {
        console.log('Control render');
      return (
      <ul>
        <li><a href="/create" onClick={function(e) {
          e.preventDefault();
          this.props.onChangeMode('create');
        }.bind(this)}>create</a></li>
        <li><a href="/update" onClick={function(e) {
          e.preventDefault();
          this.props.onChangeMode('update');
        }.bind(this)}>update</a></li>
        <li><input onClick={function(e) {
          e.preventDefault();
          this.props.onChangeMode('delete');
        }.bind(this)} type="button" value="delete"></input></li>
      </ul>
      )
    }
  }
  
  export default Control;

위와 같이 'create', 'update', 'delete' 기능을 구현하는 Control.js 파일을 새로 만들어준다.(원래 만들어놨던 컴포넌트 파일의 양식을 복사해서 그대로 사용하면 편리하다.)

'create'과 'update'는 a 태그로 만들고 전에 했던 것과 유사하게 e.preventDefualt(), this.props.onChangeMode('create')를 넣어준다. 클릭이 되었을 때, 상태 변경을 멈추고 'create'로 mode를 변경하라는 의미이다.

'delete'도 동일하게 작성하지만 button으로 생성해준다.(이유가 뭐라고 했더라...)




< App.js >

...
   <Control onChangeMode={function(_mode){
     this.setState({
       mode:_mode
     });
   }.bind(this)}></Control>
...

메인 파일이 되는 App.js에는 <Control>태그를 사용한 코드를 추가해준다.

'_mode'라는 상태를 나타내는 새로운 변수를 만들고, this.setsState()함수를 통해 state가 변경될 수 있도록 해준다.

함수 끝에 .bind(this)를 붙여주는 것을 잊지 말자!





여기까지 하면 'mode' 변수가 클릭할 때마다 상태가 바뀌는 것을 볼 수 있다.

5-4) create 구현 : mode 전환 기능

본격적으로 'create', 'update', 'delete' 기능을 구현해보자.

return (
    <div className='App'>

    <Subject 
      title = {this.state.subject.title}
      sub = {this.state.subject.sub}

      onChangePage = {function(){
        this.setState({mode:'welcome'});
      }.bind(this)}
      >
      
    </Subject> 
   
    <TOC 
    onChangePage={function(){
      this.setState({mode:'read'});
    }.bind(this)}
    data={this.state.contents}></TOC>

    <Control onChangeMode={function(_mode){
      this.setState({
        mode:_mode
      });
    }.bind(this)}></Control>
    {_article}

    </div>
  );

화면에서 맨 밑에 들어갈 문구를 _article 이라는 변수를 새로 만들어 대치해준다. 누르는 버튼에 따라 유동적으로 바뀌게 하기 위함이다.

...
if(this.state.mode === 'welcome'){
      _title = this.state.welcome.title;
      _desc = this.state.welcome.desc;
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    } 
    else if(this.state.mode === 'read'){
      var i = 0;
      while(i < this.state.contents.length){
        var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id){
          _title = data.title;
          _desc = data.desc;
          break;
        }
        i++;
      }
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    }
    else if(this.state.mode === 'create'){
        _article = <CreateContent></CreateContent>;
      }
...

그에 따라 렌더부의 윗부분도 _article로 알맞게 수정해준다.

mode의 상태에 따라 _article에 할당되는 값을 다르게 하여, 유동적으로 다른 글들이 출력될 수 있도록 하는 것이다.

그리고 'create' 버튼을 누를 때 출력되게 할 태그를 구현한 CreateContent.js 파일도 새로 만들어 적용해준다.


그러면 이렇게 mode에 따라 출력이 전환되는 것을 볼 수 있다.

5-5) create 구현 : form

이전 차시에 추가하여 'form 태그'를 이용해 입력 칸을 만들어보자.

다음은 form 태그에 대한 설명이다.

ChatGPT
"<form> 태그는 HTML에서 사용되는 요소로, 웹 페이지에서 사용자로부터 데이터를 수집하거나 제출하는 데 사용됩니다. 주로 사용자 입력을 받는 부분을 감싸는 데 사용되며, 이를 통해 데이터를 서버로 전송하거나 클라이언트 측에서 처리할 수 있습니다.
폼 안에는 다양한 입력 요소가 포함될 수 있으며, 이러한 입력 요소는 사용자로부터 데이터를 수집하는 데 사용됩니다. 예를 들어 <input>, <textarea>, <select>, <button> 등이 폼 요소로 사용될 수 있습니다. "



< CreateContent.js >

...
<form action='/create_process' method='post'
          onSubmit={function(e){
            e.preventDefault();
            alert('Submit!!!');
          }.bind(this)}
          >
          <p><input type="text" name="title" placeholder='title'></input></p>
          <p>
            <textarea name='desc' placeholder='description'></textarea>
          </p>
          <p>
            <input type='submit'></input>
          </p>
        </form>
...

'CreateContent.js'파일에 위의 코드를 추가해준다. 3개의 form 태그를 사용한 것이다.

*<input>태그와 <textarea>태그의 차이?
: < input >은 주로 짧은 텍스트 입력 또는 특정 형식의 입력(이메일, 비밀번호 등)을 받을 때 사용되며, < textarea> 는 여러 줄의 긴 텍스트 입력을 받을 때 사용됩니다. 주로 긴 텍스트 설명이나 사용자가 긴 글을 입력해야 하는 경우 사용됩니다.

'placeholder'은 입력 칸에 아무것도 입력되지 않았을 때 뜨는 기본 문구를 나타낸다.


3개의 form 태그 중 주목해야 할 것은 마지막 <input type='submit'> 부분이다.
타입을 'submit'으로 지정하면 react 고유의 기능이 발동되어, 사진처럼 '제출'이라고 쓰인 버튼이 생성되고 onSubmit 함수가 호출된다.

그렇기에 위의 코드에서 onSubmit이 호출되었을 때 어떤 작업을 수행할지 작성해준 것이다.
하지만 이 함수가 호출되면, 프로그램은 자동으로 페이지를 새로고침하려고 하기 때문에 우리는 또다시 e.preventDefault()로 새로고침을 방지해야 한다.

이후에는 알림창을 띄우도록 코드를 작성했다.


이렇게 새로고침없이 잘 작동이 되는 것을 볼 수 있다.

5-6) create 구현 : onSubmit 이벤트

.push처럼 오리지널 데이터를 건드리는 것 쓰지 않고, .concat처럼 새로운 데이터를 만드는 것 사용하기!

5-7) create 구현 : contents 변경

5-8) create 구현 : shouldComponentUpdate(번외)

.concat를 써야하는 이유! 수정 시에 원본의 '복제본'을 수정하는 것이 안전하다.

shouldComponentUpdate(){
  return false;
}

를 하면 항상 render()가 실행되지 않는다! 항상 'false'를 return하기 때문이다.

이걸 이용해서 props가 바뀌었을 때만 render()가 호출되도록 효율적으로 작동하게 할 수 있다.

< TOC.js >

class Toc extends Component {
  shouldComponentUpdate(newProps, nesState){
    console.log('===> TOC render shouldComponentUpdate',
    newProps.data
    ,this.props.data);

    if(this.props.data === newProps.data){
    return false;
    }
    return true;
  }

    render() {
      ...}

이렇게, if(this.props.data === newProps.data)의 조건문을 통해 props가 바뀌었을 때만 밑의 render()함수가 실행되도록 할 수 있다. 하지만 이렇게 해서 성능의 향상 효과가 미미하다면 그냥 하지 않아도 무방하다.

5-9) create 구현 : immutable

원본의 교체?

profile
환영합니다!

0개의 댓글

관련 채용 정보