사자자리

[React] Create 구현 본문

웹기초/생활코딩 REACT

[React] Create 구현

renne 2022. 7. 27. 18:54

목표: create를 클릭하면 App 컴포넌트의 mode가 create가 되고, 그에 따라서 기존에 있었던 컨텐츠를 표시하는 부분이 수정을 위한 인터페이스를 가지고 있는 Create 컨텐츠로 바뀐다.

 

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

class App extends Component{
  constructor(props){
    super(props);
    this.max_content_id = 3;  
    this.state = {
      mode:'read',
      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 for information"},
        {id:2, title:'CSS', desc:"CSS is for design"},
        {id:3, title:'JS', desc:"JS is for interfactive"}
      ]
    }
  }

  render(){
    var _title, _desc = null, _article = null;;
    if(this.state.mode === "welcome"){
      _title = this.state.welcome.title;
      _desc = this.state.welcome.desc;
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>  //ReadContent(이름 바꾸기 전에는 Content) 컴포넌트를 _article 변수에 준다.
    }
    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 += 1;
      }
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>  //mode가 welcome, read일 땐 ReadContent 컴포넌트가 나와야 한다.
    }
    else if(this.state.mode === "create"){
      _article = <CreateContent onSubmit={function(_title, _desc){  //각각 e.target.title.value, e.target.desc.value
        this.max_content_id += 1; //contents 배열의 id가 중복되지 않기 위해 1 증가
        /*this.state.contents.push( //push는 원본 배열의 내용을 수정하므로, concat을 사용하는 것이 권장된다.
          {id: this.max_content_id, title: _title, desc: _desc}
        );
        this.setState({contents: this.state.contents});*/

        var _contents = this.state.contents.concat( //state의 값을 직접 수정하면 React가 값이 변경되었다는 것을 모른다.
          {id: this.max_content_id, title: _title, desc: _desc}
        );
        this.setState({contents: _contents}); //setState를 통해 변경된 state값을 알려준다.
        
      }.bind(this)}></CreateContent>  //mode가 create일 때는 CreateContent 컴포넌트가 나온다.
    }

    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){
        this.setState({
          mode: _mode //create를 클릭했을 때 mode를 create로 변경한다. update의 경우엔 update로, delete의 경우엔 delete로.
        });
      }.bind(this)}></Control>
      {_article}
      </div>
    );
  }
}
export default App;
//CreateConTent.js
import React, {Component} from 'react';

class CreateContent extends Component{
    render(){
      return(
      <article>
        <h2>Create</h2>
        <form action="/create_process" method="post" onSubmit={function(e){ //submit 버튼을 포함한 form 태그에 onSubmit이라는 이벤트를 설치하면, submit 버튼을 클릭했을 때 onSubmit 이벤트가 실행된다.
          e.preventDefault(); //submit 버튼을 누르면 form 태그의 action이 가리키는 페이지로 이동하는데, 이 화면 전환을 막는다.
          this.props.onSubmit(e.target.title.value, e.target.desc.value); //title과 desc에 작성한 데이터를 인자로 받는다.
          //App.js 파일의 App 컴포넌트의 contents 배열 끝에 입력한 데이터를 추가한다.
        }.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;

 

'웹기초 > 생활코딩 REACT' 카테고리의 다른 글

[React] Update 구현  (0) 2022.07.27
[React] Immutable  (0) 2022.07.27
[React] 컴포넌트 이벤트 만들기  (0) 2022.07.20
[React] props, state, bind, 이벤트  (0) 2022.07.20
[React] Component 파일로 분리하기  (0) 2022.07.18
Comments