[React] 강의 따라하기 - 4

또여·2021년 4월 29일
0

React 강의

목록 보기
4/4

제공되는 강의는 끝까지 들으며 기본적인 react에 대한 내용은 이해된것 같다

react에는 클래스형과 함수형 두가지로 구분되는데, 함수형이 나중에 나온것이며 제공되는 기능이 적었으나 hook이라는 개념으로 그 이상의 기능을 한다고한다. 그래서 지금 프로젝트가 함수형으로 작성되었나보다

강의 들으며 따라한 결과물로 완성된 화면은

기본적인 CRUD를 구성한건데, 컴포넌트화해서 최대한 react 스럽게 따라해보았다

소스 구조로는
App
Subject
TOC
Control7
가 있고 Control 아래로
ReadContent / CreateContent / UpdateContent
으로 있다


import React, { Component } from 'react';
import TOC from "./components/TOC";
import ReadContent from "./components/ReadContent";
import CreateContent from './components/CreateContent';
import UpdateContent from './components/UpdateContent';
import Subject from "./components/Subject";
import Control from "./components/Control";
import './App.css';

class App extends Component{
  //render하기 전에 먼저 수행되는 constructor
  constructor(props){
    super(props);
    this.max_content_id = 3;
    this.state = {
      mode:'welcome',
      selected_content_id:2,
      subject:{title: 'WEB', sub: 'world wide web!'},
      welcome:{title: 'Welcome', desc: 'Hello, React!!!'},
      contents:[
        {id:1, title:'HTML', desc:'HTML is Hyper ...'},
        {id:2, title:'CSS', desc:'Csssss'},
        {id:3, title:'JavaScript', desc:'Javaaaaa'},
      ]
    };
  }
  getReadContent(){
    var i = 0;
    while(i < this.state.contents.length){
      var data = this.state.contents[i];
      if(data.id === this.state.selected_content_id){
        return data;
      }
      i = i + 1;
    }  
  }
  getContent(){
    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 _content = this.getReadContent();
      _article = <ReadContent title={_content.title} desc={_content.desc}></ReadContent>
    } else if(this.state.mode === 'create'){
      _article = <CreateContent onSubmit={function(_title, _desc){
        //변수로 title, desc를 입력받으면 content에 추가
        this.max_content_id = this.max_content_id + 1;
        
        //push는 본래값을 바꾸지만 concat은 새로만드는것
        var _content = this.state.contents.concat(
          {id:this.max_content_id,title:_title, desc:_desc}
        ); 

        this.setState({
          contents: _content,
          mode:'read',
          selected_content_id: this.max_content_id
        });
      }.bind(this)}></CreateContent>
    } else if(this.state.mode === 'update'){
      var _content = this.getReadContent();
      _article = <UpdateContent data={_content} onSubmit={
        function(_id, _title, _desc){
        var _contents = Array.from(this.state.contents);
        var i = 0;
        while(i < _contents.length){
          if(_contents[i].id === _id){
            _contents[i] = {id:_id, title:_title, desc:_desc};
            break;
          }
          i = i + 1;
        }

        this.setState({
          contents:_contents,
          mode:'read'
        });
      }.bind(this)}></UpdateContent>
    }
    return _article;
  }

  render() {
    console.log('App Render');

    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(id){
          this.setState({
            mode:'read',
            selected_content_id:Number(id)
          });
        }.bind(this)} 
        data={this.state.contents}></TOC>
        <Control onChangeMode={function(_mode){
          if(_mode === 'delete'){
            if(window.confirm('Really?')){
              var _contents = Array.from(this.state.contents);
              var i = 0;
              var deletedTitle = '';
              while(i < _contents.length){
                if(_contents[i].id === this.state.selected_content_id){
                  deletedTitle = _contents[i].title;
                  _contents.splice(i, 1);
                  break;
                }
                i = i + 1;
              }
              this.setState({
                mode:'welcome',
                contents:_contents
              });
              alert('Deleted : ' + deletedTitle);
            }
          } else{
            this.setState({
              mode:_mode
            })
          }
        }.bind(this)}></Control>
        {this.getContent()}
      </div>
    );
  }
}

export default App;

App.js

DB가 없어서 constructor에서 state에 현재 뿌려줄 데이터를 임의로 저장해놓고 이 데이터를 현재 component에서 쓰거나 props로 넘기거나

1. 상위 컴포넌트에서 하위 컴포넌트로

        <Subject 
          title={this.state.subject.title} 
          sub={this.state.subject.sub}
          onChangePage={function(){
            this.setState({mode:'welcome'});
          }.bind(this)}>
        </Subject>

subject의 컴포넌트로 title, sub, onChangePage를 props로 넘김(사실 onChangePage도 넘긴다는게 맞는 표현인지는 모르겠다)
이렇게 되면 상위 컴포넌트인 App에서 사용하는 값을 Subject 컴포넌트로 넘겨서 사용할 수 있게 만듦

this.props.title
      <header>
        <h1><a href="/" onClick={function(e){
          e.preventDefault();
          this.props.onChangePage();
        }.bind(this)}>{this.props.title}</a></h1>
        {this.props.sub}
      </header>

2. 하위 컴포넌트에서 상위 컴포넌트로

1번의 경우는 'props로 넘긴다'라는 표현을 쓰는데, 2번의 경우는 어떻게 표현하는지 모르겠다
하위 컴포넌트인 Control 컴포넌트는

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

이렇게 생겼는데, 중간에

this.props.onChangeMode('update');

이런 부분이 있다. 넘겨받은 props의 'onChangeMode'라는 함수(?)에 어떠한 값을 넣어주는데

        <Control onChangeMode={function(_mode){
          if(_mode === 'delete'){
            if(window.confirm('Really?')){
              var _contents = Array.from(this.state.contents);
              var i = 0;
              var deletedTitle = '';
              while(i < _contents.length){
                if(_contents[i].id === this.state.selected_content_id){
                  deletedTitle = _contents[i].title;
                  _contents.splice(i, 1);
                  break;
                }
                i = i + 1;
              }
              this.setState({
                mode:'welcome',
                contents:_contents
              });
              alert('Deleted : ' + deletedTitle);
            }
          } else{
            this.setState({
              mode:_mode
            })
          }
        }.bind(this)}>
        </Control>

첫줄에

function(_mode){

이 부분에서 _mode 가 하위 컴포넌트에서 받아온 'create'와 같은 값이 되는것
하단에

	else{
            this.setState({
              mode:_mode
            })

이렇게 함으로써 현재 mode를 setState를 통해 변경해서 하위 컴포넌트로부터 값을 받을 수 있다


React의 기본적인 개념과 javascript를 전혀 몰랐지만, 이제는 읽고 쓰는것 정도는 가능해진 것 같다
기본적인 내용을 담고있는 강의, 소스니 종종 잊을때 마다 봐줄 필요가 있겠다

https://github.com/Upisdown62/react_tutorial.git

혹시 몰라서 메모

profile
기록 열심히하는 개발자인척

0개의 댓글