⑥ Create 기능 구현

hhkim·2019년 11월 17일
0

생활코딩 React

목록 보기
6/8
post-thumbnail

🔗 생활코딩 React

1. 베이스 캠프

  • props
    - read-only
    • 컴포넌트 안에서 변경 불가
    • 이벤트를 통해 변경 가능
  • state
    - 비동기식
    • setState()로 변경 가능

2. create 구현

1) 소개

  • CRUD(Create Read Update Delete)
  • 동적으로 요소를 추가하는 기능 구현

2) mode 변경 기능

  • Control.js 생성 후 App.js에 import
// Control.js
class Control extends Component {
    render(){
      return (
        <ul>	// 각 링크 클릭 시 onChangeMode 함수 호출
          <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){	// delete는 위험하니까 버튼으로 생성
            e.preventDefault();
            this.props.onChangeMode('delete');
          }.bind(this)} type="button" value="delete"></input></li>
        </ul>
      );
    }
  }
// App.js
// onChangeMode 함수의 파라미터로 전달된 _mode 값을 state의 mode에 셋
<Control onChangeMode={function(_mode){
    this.setState({
      mode:_mode
    })
  }.bind(this)}>
</Control>

3) mode 전환 기능

  • 기존 Content 컴포넌트를 ReadContent로 수정
  • CreateContent.js 파일 생성하고 App.js에 import
  • 기존 App.js의 <ReadContent>...</ReadContent> 부분을 가변적으로 만들기 위해 {_article}로 대체
// App.js
  render() {
    var _title, _desc, _article = null;	// _artlcle 변수 선언
    // mode가 welcome이나 read면 기존 ReadContent가 _article 자리에 들어감
    if(this.state.mode === 'welcome'){
      ...
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    }else if(this.state.mode === 'read'){
      ...
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    // mode가 create면 _article에 CreateContent가 들어감
    }else if(this.state.mode === 'create'){
      _article = <CreateContent title={_title} desc={_desc}></CreateContent>
    }
    return (
      <div className="App">
       ...
        <Control ...>
        </Control>
        {_article}
      </div>
    );
  }

4) form

  • CreateContent.js에 폼 추가
<article>
  <h2>Create</h2>
  <form action="/create_process" method="post"
    onSubmit={function(e){
      e.preventDefault(); // 페이지 전환 방지
    }.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>

5) onSubmit 이벤트

// App.js
...
}else if(this.state.mode === 'create'){
  _article = <CreateContent onSubmit={function(_title, _desc){
        console.log(_title, _desc);	// 값 잘 들어오나 찍어보기
      }.bind(this)}></CreateContent>
}
// CreateConent.js
<form action="/create_process" method="post"
  onSubmit={function(e){
    e.preventDefault(); // 페이지 전환 방지
    this.props.onSubmit(  // form(e) - target -  name 값(title/desc) - value
      e.target.title.value,	
      e.target.desc.value
    );
  }.bind(this)}
  >

🤦‍♀️
오... 잘 쓰면 엄청 유용할 거 같고 효율적일 거 같은데 머리가 너무 복잡하다.
계속 정리하고 연습해봐야 언제 어떻게 써야 할지 감이 올 것 같다.

6) contents 변경

  • form에서 받은 데이터를 state의 contents에 추가
// App.js
constructor(props){
    super(props);
    this.max_content_id = 3;	// max_content_id 선언
    ...
  }
...
}else if(this.state.mode === 'create'){
    _article = <CreateContent onSubmit={function(_title, _desc){
          this.max_content_id = this.max_content_id + 1;	// max_content_id 증가
          var _contents = this.state.contents.concat(	// concat 함수로 contents에 정보를 추가한 _contents 선언
            {id:this.max_content_id, title:_title, desc:_desc}
          );
          this.setState({
            contents:_contents	// state의 contents 변경
          });
    }.bind(this)}></CreateContent>
}

7) shouldComponentUpdate

  • push
    : 원본이 바뀜
var a = [1, 2]
a.push(3);
console.log(a); // [1, 2, 3]
  • concat
    : 원본은 바뀌지 않고, 원본이 수정된 복제본 생성
var a = [1, 2]
a.concat(3);
console.log(a); 	// [1, 2]

👉 push 대신 concat을 사용하면 원본이 남아있으므로 코드가 일관되고 덜 혼란스러움

  • shouldComponentUpdate
    - 부모 컴포넌트가 업데이트되면 자식 컴포넌트들은 자동으로 다시 로드(렌더)됨
    • shouldComponentUpdate 함수를 사용하면 자식 컴포넌트에 변경할 내용이 없다면 render 함수를 실행하지 않음
// TOC.js
class TOC extends Component {
  shouldComponentUpdate(newProps, newState){  // 새롭게 바뀐 값, 기존 값에 접근 가능
    console.log('===>TOC render shouldComponentUpdate', 
    newProps.data // 새로운 값
    ,this.props.data  // 기존 값
    ); // concat이 아니라 push를 사용하면 기존값 === 새로운 값
    if(this.props.data === newProps.data){
      return false;	// render 호출하지 않음
    }
    return true; // render 호출
  }
    render(){
      ...
    }
  }

8) immutable

  • 원본이 불변하는 특성 (예: concat)
  • Array.from()
    - 배열 복제
var a = [1, 2];
var b = Array.from(a);	// a로 배열 생성(복제)
console.log(a, b, a===b);	// [1, 2] [1, 2] false

👉 pushArray.from()을 이용해서 복제한 후에 사용

  • Object.assign()
    - 객체 복제
    var a = {name:'bono'};
    var b = Object.assign({}, a);	// 빈 객체에 a를 넣어서 새로운 객체 생성
    console.log(a, b, a===b);	// {name:'bono'} {name:'bono'} false

🙆‍♀️
shouldComponentUpdateimmutable은 성능에 문제가 생길 때 더 알아볼 것!

0개의 댓글