본문 바로가기

그 땐 Front했지/그 땐 React했지

[생활코딩/React] 19.create 구현

728x90

참고자료: 유튜브 생활코딩 React https://www.youtube.com/playlist?list=PLuHgQVnccGMCRv6f8H9K5Xwsdyg4sFSdi

 

1.  소개


📌CRUD: Create Read Update Delete

지금까지는 Read만 해왔기 때문에 나머지 CUD를 해보자!
create 버튼을 누르면 TOC 부분에 리스트가 하나 더 생기는 기능을 만들것이다!

 

2.  mode 변경 기능


//Control.js
import React, { Component } from 'react';

class Subject extends Component {
    render () {
      return (
        <ul>
          <li><a href='/create'>create</a></li>
          <li><a href='/update'>update</a></li>
          <li><input type="button" value="delete"></input></li>
        </ul>
      );
    }
  }

  export default Subject;

👉🏻create, update, delete 버튼을 담은 component를 Control.js 파일에 만들어둔다.

✍🏻delete만 a tag를 사용하지 않는 이유: 해당 링크로 들어가면 의도치 않게 삭제해버릴 수도 있기 때문이다.

👉🏻이런 느낌!ㅋㅋ

//App.js
return (
  <div className="App">
	...중략...
    <Control
      onChangeMode={function(_mode){
        this.setState({
          mode:_mode
        })
      }.bind(this)}>
    </Control>
	...중략...
  </div>
);

👉🏻return에 Control이라는 component를 추가해주고 onChangeMode라는 props를 넘겨준다. 이 props는 state의 mode값을 변경시켜준다.

//Control.js
  <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 type="button" value="delete" onClick={function(e){
    e.preventDefault();
    this.props.onChangeMode('delete');
  }.bind(this)}></input></li>

👉🏻각 tag에 onClick 이벤트를 부여한다. props의 onChangeMode각 버튼에 맞는 mode값을 넘겨준다.

👉🏻각 버튼에 맞게 mode값이 잘 변하고 있다!

 

3.  mode 전환 기능


//ReadContent.js
import React, { Component } from 'react';

class ReadContent extends Component {
    render () {
      return (
        <article>
            <h2>{this.props.title}</h2>
            {this.props.desc}
        </article>
      );
    }
  }

  export default ReadContent;
//CreateContent.js
import React, { Component } from 'react';

class CreateContent extends Component {
    render () {
      return (
        <article>
            <h2>Create</h2>
            <form>

            </form>
        </article>
      );
    }
  }

  export default CreateContent;

👉🏻Content component를 ReadContent로 변경하고 CreateContent component를 새로 생성한다.

//App.js
  render () {
    var _title, _desc, _article = null;
    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 = i + 1;
      }
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    } else if (this.state.mode === 'create') {
      _article = <CreateContent></CreateContent>
    }
    return (
    ...중략...
    )
  }

👉🏻render 부분에 state의 mode값이 create일 때는 CreateContent component를 출력하고 그 이외의 상황일 때는 ReadContent component를 출력한다.

 

4. form


//CreateContent.js
  return (
    <article>
        <h2>Create</h2>
        <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>
    </article>
  );

👉🏻return 부분에 아이템을 생성(create)할 수 있는 form을 만들어준다.

✍🏻onSubmit: submin input을 누르면 여기해 해당하는 동작을 수행한다.(이건 HTML의 기능)

 

5. onSubmit 이벤트


//CreateContent.js
<form action="/create_process" method="post"
  onSubmit={function(e){
    e.preventDefault();
    this.props.onSubmit(
      e.target.title.value,
      e.target.desc.value
    );
  }.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>

👉🏻onSubmit 함수에 title과 desc input에 담긴 내용을 전달한다!

👉🏻input에 입력한 내용이 e.target.title.value로 console에 검색하면 알맞게 잘 나오고 있다!

 

6. contents 변경


//App.js
  constructor(props) {
    super(props);
    this.max_content_id = 3;
    this.state = {...중략...}
  }
  render () {
	...중략...
    } else if (this.state.mode === 'create') {
      _article = <CreateContent onSubmit={function(_title, _desc){
        this.max_content_id = this.max_content_id + 1;
        var _contents = this.state.contents.concat(
          {id: this.max_content_id, title: _title, desc: _desc}
        )
        this.setState({
          contents: _contents
        })
      }.bind(this)}></CreateContent>
    }
    return (
    ...중략
    )
  }

👉🏻먼저 contents state의 길이를 담고 있는 max_content_id 변수를 정의해준다.

👉🏻그리고 render에서 mode값이 create일 때 onSubmit props를 통해 contents 내용을 변경해준다. 받아온 인자값을 content의 형식에 맞게 적어서 추가해준다. 그리고 다시 setState를 이용해 react가 변경사항을 적용할 수 있도록 해준다.

✍🏻concat: 기존의 데이터를 변경하지 않고 데이터를 추가할 수 있다.

 

 

7. shouldComponentUpdate


하나의 동작을 할 때마다 TOC(리스트 부분) component가 동작한다. mode의 값이 read로 변하는 사항은 TOC와 전혀 연관이 없는 상황인데도 TOC가 동작한다.
이러한 점은 프로젝트가 커지면 중요한 이슈로 작용할 수 있다. 때문에 react 개발자의 영역에서 선택적으로 render 함수를 호출할 수 있는 기능이 있다.
//TOC.js
shouldComponentUpdate(newProps, newState) {
  if(this.props.data === newProps.data) {
    return false;
  }
  return true;
}

👉🏻shouldComponentUpdate는 해당 component의 render 함수를 호출할지 말지의 여부를 결정한다. true를 return하면 호출, false면 호출하지 않는다. 그리고 이 함수는 2개의 매개 변수를 받는다.

  • newProps: props가 바뀌었을 때 바뀐 값
  • newState: state가 바뀌었을 때 바뀐 값

 

8. immutable


원본을 변형하지 않으면서 concat이 아닌 push를 사용하고 싶다면?
//App.js
var newContents = Array.from(this.stat.contents);
newContents.push({id: this.max_content_id, title: _title, desc: _desc})
this.setState({
  contents: newContents
})

👉🏻.from: 리스트를 복제한다.

👉🏻.assign: 객체를 복제한다.

✍🏻Immutable을 검색해서 더 알아보자! 얘는 무조건 원본을 복제해서 반환한다!

728x90