React

생활코딩 React 강의 (8) - create 구현

joy_lee 2021. 9. 9. 18:13

mode변경기능

정보를 읽는 것은 구현했으니 나머지 Create, Update, Delete기능을 위해 새로운 컴포넌트를 만든다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component } from 'react';
 
class Control extends Component {
  render() {
    console.log("Control 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 Control
cs

Control은 props로 onChangeMode라는 이벤트 함수를 전달받을 것이다. 이벤트를 통해 mode를 App 컴포넌트에 전달하도록 만들어야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>
cs

클릭했을 때 props를 통해 전달된 onChangeMode()를 실행하도록 한다.

onChangeMode는 App컴포넌트에서 전달된 _mode로 state의 mode를 변경하는 함수다.

1
2
3
4
5
<Control onChangeMode={function(_mode){
  this.setState({
    mode: _mode
  })
}.bind(this)}></Control>
cs

리스트를 클릭하면 mode가 바뀌는 것을 확인할 수 있다.

 

mode전환 기능

mode에 따라 다른 컴포넌트를 화면에 보여주려면 App이 render()에서, return전에 정해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// CreateComponent를 새로 만든다
import CreateContent from "./components/CreateContent"
 
class App extends Component {
    render() {
        var _title, _desc, _article = null;
        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>
        } else if (this.state.mode == "create") {
              _article = <CreateContent></CreateContent>
        }
    }
    return {
        // ...
        {_article}
    }
}
cs

render()안에 _article이라는 변수를 새로 만들어 mode에 따라 다른 Component를 입력받도록 한다.

임시로 만든 CreateComponent가 잘 나타나는 것을 확인할 수 있다.

 

form

새로운 정보를 입력받기 위한 form을 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// CreateContent.js
import React, { Component } from 'react';
 
class CreateContent extends Component {
    render() {
      return (
        <article>
              <h2>Create</h2>
              <form action="/create_process" method="post">
                <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
cs

form에서 action="/create_process" method="post"로 설정해준다.

(action: 뒤의 나온 페이지로 이동함 / method: post방식(url에 노출 안됨)/get(url에 나타남))

 

제출된 form의 정보를 전달하기 위해서는 이벤트를 사용해야 한다.

1
2
3
4
5
6
7
8
<form action="/create_process" method="post"
    onSubmit={function(e){
        e.preventDefault();
        this.props.onSubmit(e.target.title.value, e.target.desc.value)
    }.bind(this)}
>
// ...
</form>
cs

e.target은 이벤트가 발생되는 곳을 말하며, 그 뒤의 title과 desc는 form 안에 있는 요소들의 name정보에 따라 정해진다.

이렇게 전달받은 정보를 App의 onSubmit에서 처리해줘야 한다.

 

새롭게 저장될 정보의 id값을 위해 새로운 변수를 만든다.

1
2
3
4
5
6
7
constructor(props){
    super(props);
    this.max_content_id = 3;
    this.state = {
    // ...
    }
}
cs

App의 생성자함수안에 max_content_id를 만든다.

새로운 자료를 저장할 때에만 필요한 것이고, UI에 영향을 주지 않아야 하는 정보이기 때문에 state안에 저장하지 않는다.(불필요한 랜더링 방지)

1
2
3
4
5
6
7
8
9
10
11
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>
}
cs

state 안의 요소들을 변경시킬 땐 push와 같이 원본을 변화시키는 것이 아닌 concat으로 원본은 남겨두고 사본을 만드는 방법으로 변경시켜야 한다.

 

shouldComponentUpdate()

앱이 커지게되면 성능 향상을 위해 props의 값 변경 여부 따라 render()호출을 결정하도록 해야한다.

shouldComponentUpdate()는 반환값에 따라 true이면 render()를 호출하고, false이면 render()를 호출하지 않는다.

https://ko.reactjs.org/docs/react-component.html#shouldcomponentupdate

nextProps와 nextState를 인자로 받는데, 그것과 this.props, this.state를 비교해 전달받은 값의 변화가 있는지 확인할 수 있다. 변화 여부에 따라 렌더할것인지 결정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
class TOC extends Component{
    shouldComponentUpdate(newProps, newState) {
          if(this.props.data === newProps.data){
        return false;
      }
      return true;
    }
    render() {
        // ...
    }
}
cs

shouldComponentUpdate를 사용하기 전에는 기본값이 true이므로, 상위의 App컴포넌트가 새롭게 render 될때마다 하위의 TOC, Subject등 모든 컴포넌트들이 새롭게 render되었다. 이것을 막기 위해 TOC컴포넌트의 render()이전에 shouldComponentUpdate()를 만들어 새롭게 입력된 newProps.data와 기존의 this.props.data를 비교해 다를 때만 render되도록 설정할 수 있다.(같으면 return false;)

 

만약 App에서 contents의 내용을 push를 통해 바꿨다면, react는 바뀐 원본을 this.props.data라고 인식한다. 그러면 자료가 바꼈지만 this.props.data 와 newProps.data가 동일해져서 shouldComponentUpdate로 확인할 수 없다.

push()를 사용한 경우 / TOC가 render되지 않았다
concat()을 사용한 경우 / 변화를 감지해 TOC가 render되었다

 

TOC안의 render()가 실행될 때 마다 console.log로 확인할 수 있도록 설정했더니, App컴포넌트의 render()가 실행될 때마다 TOC의 render()도 실행되는 것을 확인할 수 있다.

이번에는 TOC안에 shouldComponentUpdate()와 render()가 실행될 때마다 콘솔에서 확인할 수 있도록 했다.

그랬더니 TOC가 업데이트되지 않는 경우에는 shouldComponentUpdate()만 실행되고 render()는 실행되지 않는 것을 알 수 있다. 새로운 데이터를 입력해 새로운 리스트를 만들어야 할 때만 shouldComponentUpdate()가 먼저실행되어 render()여부를 확인하고, 변경이 있음을 감지해 render()가 실행되도록 한다.

 

 

 

immutable

= 원본을 바꾸지 않는다

원본을 복제하여 수정할 값을 할당한 후, 원본의 경로를 바꾸면서 react에서 불안정성을 줄일 수 있다.

immutable.js 등 라이브러리를 활용하는 것도 가능하니 상황에 맞게 이를 활용하도록 하는 것이 좋다.

https://velopert.com/3486

 

 

참고한 페이지

생활코딩 React 강의

19.1 react 구현 : 소개

19.2 react 구현 : mode 변경 기능

19.3 react 구현 : mode 전환 기능

19.4 react 구현 : form

19.5 react 구현 : onSubmit 이벤트

19.6 react 구현 : contents 변경

19.7 react 구현 : shouldComponentUpdate

19.8 react 구현 : immutable

https://youtu.be/nwwJ2xU7E8w

 

React - 19.1. create 구현 : 소개

React를 처음 시작하는 분들에게 권하는 강의입니다. 이 수업은 아래와 같은 웹애플리케이션을 React를 이용해서 완성하는 것이 큰 목표입니다. https://egoing.github.io/react-tutorial-example/ 소스코드

youtu.be

https://ko.reactjs.org/docs/react-component.html#shouldcomponentupdate

 

React.Component – React

A JavaScript library for building user interfaces

ko.reactjs.org

https://velopert.com/3486

 

React ❤️ Immutable.js – 리액트의 불변함, 그리고 컴포넌트에서 Immutable.js 사용하기 | VELOPERT.LOG

이 포스트는 React 에서는 불변함 (Immutability) 를 지키며 상태 관리를 하는 것을 매우 편하게 해주는 라이브러리 Immutable.js 에 대해서 알아보겠습니다. 서론 리액트를 사용하신다면, Immutability 라는

velopert.com