이전에 살펴본 생성 기능을 구현해보자.
우선 <Navi>
와 <Arti>
사이에 create
,update
,delete
라고 하는 세가지 mode
로 진입하는 버튼을 만들자.
<Navi> 컴포넌트
<ul> <li><a href="/create">create</a></li> <li><a href="/update">update</a></li> <li><input type="button" value="delete">delete</input></li> </ul>
create, upadeta, 그리고 read는 어떤 특정한 페이지로 이동해서 오퍼레이션이 실행 된다.
이러한 상황에서 delete 버튼
을 클릭할 때 실제로 삭제가 일어나게 하는 경우에 링크를 쓰게 되면 문제가 발생할 수 있다.
예를 들어 어떤 사용자들이 페이지 방문을 할 때 좀 더 빨리 방문할 수 있게 미리 방문을 해 두는 소프트웨어가 깔려 있다면 delete로 되어 있는 부분도 미리 방문을 해버리게된다면? 삭제이벤트가 실행되는 문제가 있다.
따라서 delete 같은 경우는 링크 페이지 개념이 아니라 버튼과 같은 오퍼레이션 개념의 기능을 사용하도록 한다.
Control.js
import React, { Component } from 'react'; class Control extends Component { render() { return( <ul> <li><a href="/create">create</a></li> <li><a href="/update">update</a></li> <li><input type="button" value="delete">delete</input></li> </ul> ); } } export default Control;
이렇게 만든 코드들을
<Control>
라고 하는 컴포넌트로 만들어 외부의Control.js
파일로 만든다.
App.js
import Control from "./components/Control"; // 컴포넌트 불러오기 //`App.js > render` Navi컴포넌트의 밑에 배치 ... </Navi> <Control></Control> ...
아까와 똑같아 보이지만 Control.js
라는 파일로 분리시킨 것이다.
<Control>
에서 3개 중에 하나를 클릭했을 때 어떤 일이 일어나게 하기 위해서 onChangeMode
라는 이벤트를 정의해준다.
이것은 이벤트가 실행 됐을 때 실행되어야 하는 함수인 이벤트 핸들러(Evenet Handler)
를 설치하는 것이다.
링크를 클릭했을 때 onChangeMode
라는 핸들러가 실행되게 하기 위해 <a>
태그에 onClick
속성을 추가한다.
Control.js
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;
onChange
가 호출될 때 어떤 역할을 하는 링크인지 알 수 있도록 첫 번째 인자를 받을 수 있어야 한다.
mode
라는 값으로 첫번째 인자를 받고 함수 안에서는 mode
라는 변수로 현재 상태가 전달이 되게 된다.
onChangeMode
함수가 호출될 때마다 앱 컴퍼넌트의 mode state
값을 바꾸기 위해서는 setState()
함수를 사용한다.
App.js > render > Control 컴포넌트 영역
<Control onChangeMode={function (_mode) { this.setState({ mode: _mode }); }.bind(this)</ Control>
이제 create
를 클릭하면 mode
의 값이 create
로 바뀌고, update
를 클릭하면 update
, delete
를 클릭하면 delete
로 바뀌는 것을 확인할 수 있다.
현재 상태에 따라서 mode라는 state
값이 바뀌게 된 것이다.
이번에는 create를 클릭할 때 쓰기에 사용될 컴포넌트로 교체시키는 작업을 해보자.
현재 이 애플리케이션은 create를 클릭했을 때 <Arti>
컴포넌트는 읽기에서 사용되는 컴포넌트다.
이번 시간에는 create를 클릭하면 쓰기에서 사용될 컴포넌트로 교체시키는 작업을 해보자.
이를 위해 기존에 있었던 읽기 컴퍼넌트 이름을 <ReadArti>
로 수정한다.
<App>
컴포넌트의 mode의 값이 create
라면 <CreateArti>
컴포넌트 로 바뀌고
<App>
컴포넌트에 mode의 값이 read
라면 <ReadArti> 컴포넌트
로 바뀌도록 하자.
기존에 있던 <Arti>
컴포넌트 이름을 <ReadArti>
로 바꾸고 파일의 이름도 ReadArti.js
로 변경한다.
ReadArti.js
import ReadArti from "./components/ReadArti" <ReadArti title = {_title} desc={_desc}</ReadArti>
이전파일과 똑같지만 이름이 좀 더 보기좋게 바뀌게 되었다.
ReadArti.js
와 마찬가지로 CreateArti.js
파일을 추가한다.
이 파일에서는 Form 을 구현할 것이다.
CreataeArti.js
(기존 ReadArti.js 를 복사해서 수정)import React, {Component} from 'react'; class CreateArti extends Component{ render(){ console.log("Arti Render"); return( <article> <h2>Create</h2> <form> ... </form> </article> ); } } export default CreateArti;
App.js
// App.js 파일에 import 추가
import CreateArti from "./components/CreateArti"
지금까지 수정 작업을 통해 <Control>
에서 create
를 클릭하면 <App>
컴포넌트의 mode가 create로 바뀌게 된다.
이때 <ReadArti>
가 있는 부분을 <CreateArti>
로 교체하는 코드를 작성해보자.
App.js
파일로 들어가 mode의 값에 따라 <article>
영역이 교체되는 코드를 <ReadArti>
영역이 가변적으로 바뀔 수 있도록 하기 위해 _article
이라는 변수로 처리한다.
App.js
render(){ var _title, _desc, _article = null; // <- _article : 컴포넌트가 담길 변수 if (this.state.mode === 'welcome') { _title = this.state.welcome.title; _desc = this.state.welcome.desc; _article = <ReadArti title = { _title } desc = { _desc }</ ReadArti> } 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 = i + 1; } }
App.js > render > Control가 끝나는 컴포넌트 밑에
}.bind(this)}></Control> // Control 컴포넌트 {_article} // 최종적으로 content가 출력될 컴포넌트를 가진 변수
기존에 있었던 <ReadArti>
를 _article
이라는 변수에 준 것이다.
그리고 mode가 read일 때도 <ReadArti>
가 나오는건 마찬가지이기 때문에 else if 구문에도 추가해 준다.
위 코드를 통해 mode가 welcome이나 read인 경우에는 _article
의 값이 <ReadArti>
로 되게 된다.
그럼 그에 따라서 {_article}
부분에 <ReadArti>
가 나온다.
브라우저에서 링크를 클릭했을 때 <ReadArti>
가 잘 나오는 걸 확인할 수 있다.
다음으로 mode가 create일 때 <CreateArti>
가 화면에 출력되도록 작성한다.
App.js
render(){ var _title, _desc, _article = null; // <- _article : 컴포넌트가 담길 변수 if (this.state.mode === 'welcome') { ... } else if (this.state.mode === 'read') { ... } else if (this.state.mode === 'create'){ // create 모드 _article = <CreateArti></CreateArti> } }
- 결과
<App>
컴포넌트 mode가 create일 때 <ReadArti>
가 <CreateArti>
로 바뀌게 된다.
웹 페이지에 <CreateArti>
의 <h2>
태그 부분이 Create로 잘 출력되는 것을 확인할 수 있다.