
/components/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;
App.js
import Control from './components/Control'
<TOC>...</TOC>
<Control onChangeMode={function(_mode){
this.setState({
mode:_mode
})
}.bind(this)}></Control>
Content.js -> ReadContent.js로 이름 변경CreateContent.js 추가<ReadContent> 영역 교체App.js// _article 변수 추가
var _title, _desc, _article = null;
if (this.state.mode === 'welcome') {
...
// _article 변수에 ReadContent 담아주기
_article = <ReadContent title={_title} desc={_desc}></ReadContent>;
}else if (this.state.mode === 'read') { // mode가 read일 때도 나와야 함
...
_article = <ReadContent title={_title} desc={_desc}></ReadContent>;
}else if(this.state.mode === 'create') { // mode가 create일 때 CreateContent
_article = <CreateContent></CreateContent>;
}
...
// <ReadContent></ReadContent>
{_article}
CreateContent.js 구현import React, { Component } from 'react';
class CreateContent extends Component {
render() {
return (
<article>
<h2>Create</h2>
{/* ⭐post 방식: url 노출 안됨 */}
{/* ⭐onSubmit: submit버튼 클릭 되었을때 이벤트 실행 */}
<form action='/create_process' method='post' onSubmit={function(e){
e.preventDefault(); // ⭐페이지 전환없이
alert("Submit!!!");
}.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;
App.js
else if(this.state.mode === 'create') {
_article = <CreateContent onSubmit={function(_title, _desc){
// add content to this.state.contents
}.bind(this)}></CreateContent>;
}
CreateContent.js
e.preventDefault(); // 페이지 전환없이
this.props.onSubmit(
e.target.title.value,
e.target.desc.value,
);
alert("Submit!!!");
App.js
1) push 사용 (별로 권장하지 않음)
// ⭐객체의 값으로 한 이유: max_content_id는 데이터를 puch(추가)할 때 id값으로 무엇을 할 것인가
// 사용하는 용도일 뿐 ui에는 영향을 주지않음.
// ⭐state 값으로 할 경우 불필요한 렌더링 발생 가능성 있음. 비합리적
this.max_content_id = 3;
this.state = {
}
else if(this.state.mode === 'create') {
_article = <CreateContent onSubmit={function(_title, _desc){
// add content to this.state.contents
this.max_content_id = this.max_content_id + 1;
this.state.contents.push({id:this.max_content_id, title:_title, desc:_desc});
this.setState({
contents: this.state.contents
});
}.bind(this)}></CreateContent>;
}
push는 원본을 바꿈,
concat은 원본을 바꾸지 않음, 원본의 복제본에 새로운 데이터 추가
2) concat 사용
var _contents = this.state.contents.concat({id:this.max_content_id, title:_title, desc:_desc})
this.setState({
contents: _contents
});
render함수 실행 시킬지 말지 결정하는 함수
프로젝트의 규모가 작을 땐 상관없지만 규모가 커지면 이슈 발생
shouldComponentUpdate(newProps, newState) {
return false;
}
render 호출 되기전에 실행된다.
return true : render 호출
return false : render 호출되지 않음
newProps.data , this.props.data => 새롭게 바뀐 값과 이전 값에 접근 가능
TOC.js
shouldComponentUpdate(newProps, newState){
if(this.props.data === newProps.data) {
return false;
}
return true;
}
유사 객체,
베열 a가 있다고 가정, a와 내용은 같지만 a===b의 형태로 비교해 보면 false!
var newContens = Array.from(this.state.contents);
newContens.push({id:this.max_content_id, title:_title, desc:_desc})
this.setState({
contents: newContens
});
⚡ 리액트의 불변성 immutable