[React] ③ Create기능

지연·2024년 2월 5일
post-thumbnail

1. mode 변경 기능

/components/Control.js'

  • delete 같은 경우는 create, update와 달리 링크 개념이 아니라 버튼으로 쓰는게 맞음!
import React, { Component } from 'react';

class Control extends Component {
  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;

App.js

import Control from './components/Control'

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

2. mode 전환 기능

  1. 기존 Content.js -> ReadContent.js로 이름 변경
  2. CreateContent.js 추가
  3. mode에 따라서 <ReadContent> 영역 교체
    App.js
// _article 변수 추가
var _title, _desc, _article = null;

if (this.state.mode === 'welcome') {
	 ...
  	// _article 변수에 ReadContent 담아주기
     _article = <ReadContent title={_title} desc={_desc}></ReadContent>;
}else if (this.state.mode === 'read') { // mode가 read일 때도 나와야 함
  ...
  _article = <ReadContent title={_title} desc={_desc}></ReadContent>;
}else if(this.state.mode === 'create') { // mode가 create일 때 CreateContent
      _article = <CreateContent></CreateContent>;
}

...
// <ReadContent></ReadContent> 
{_article}
  1. CreateContent.js 구현
import React, { Component } from 'react';

class CreateContent extends Component {
    render() {
        return (
            <article>
                <h2>Create</h2>
                {/* ⭐post 방식: url 노출 안됨 */}
                {/* ⭐onSubmit: submit버튼 클릭 되었을때 이벤트 실행 */}
                <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>
        );
    }
}

export default CreateContent;

3. onSubmit 이벤트

App.js

else if(this.state.mode === 'create') {
      _article = <CreateContent onSubmit={function(_title, _desc){
        // add content to this.state.contents
      }.bind(this)}></CreateContent>;
    }

CreateContent.js

e.preventDefault(); // 페이지 전환없이 
this.props.onSubmit(
	e.target.title.value,
    e.target.desc.value,
);
alert("Submit!!!");

4. Contents 변경

App.js

1) push 사용 (별로 권장하지 않음)

// ⭐객체의 값으로 한 이유: max_content_id는 데이터를 puch(추가)할 때 id값으로 무엇을 할 것인가 
// 사용하는 용도일 뿐 ui에는 영향을 주지않음.
// ⭐state 값으로 할 경우 불필요한 렌더링 발생 가능성 있음. 비합리적
this.max_content_id = 3; 
this.state = {
  
}

else if(this.state.mode === 'create') {
      _article = <CreateContent onSubmit={function(_title, _desc){
        // add content to this.state.contents
        this.max_content_id = this.max_content_id + 1;
        this.state.contents.push({id:this.max_content_id, title:_title, desc:_desc});
        this.setState({
          contents: this.state.contents
        });
      }.bind(this)}></CreateContent>;
}

push는 원본을 바꿈,
concat은 원본을 바꾸지 않음, 원본의 복제본에 새로운 데이터 추가

2) concat 사용

var _contents = this.state.contents.concat({id:this.max_content_id, title:_title, desc:_desc})
this.setState({
	contents: _contents
});

❤shouldComponentUpdate

  • render함수 실행 시킬지 말지 결정하는 함수

  • 프로젝트의 규모가 작을 땐 상관없지만 규모가 커지면 이슈 발생

    shouldComponentUpdate(newProps, newState) {
    return false;
    }

  • render 호출 되기전에 실행된다.

  • return true : render 호출

  • return false : render 호출되지 않음

  • newProps.data , this.props.data => 새롭게 바뀐 값과 이전 값에 접근 가능

TOC.js

shouldComponentUpdate(newProps, newState){
        if(this.props.data === newProps.data) {
            return false;
        }
        return true;
}
  • 📍주의 push 사용 할 경우 원본 값이 바뀌기 때문에 새로운 값과 이전 값이 완전히 같아짐

⭐ Array.from

유사 객체,
베열 a가 있다고 가정, a와 내용은 같지만 a===b의 형태로 비교해 보면 false!

  • 배열의 경우에만 사용
var newContens = Array.from(this.state.contents);
newContens.push({id:this.max_content_id, title:_title, desc:_desc})

this.setState({
	contents: newContens
});
  • 객체의 경우에는 Object.assign({}, a)

⚡ 리액트의 불변성 immutable

0개의 댓글