setState()
로 변경 가능import
// Control.js
class Control extends Component {
render(){
return (
<ul> // 각 링크 클릭 시 onChangeMode 함수 호출
<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){ // delete는 위험하니까 버튼으로 생성
e.preventDefault();
this.props.onChangeMode('delete');
}.bind(this)} type="button" value="delete"></input></li>
</ul>
);
}
}
// App.js
// onChangeMode 함수의 파라미터로 전달된 _mode 값을 state의 mode에 셋
<Control onChangeMode={function(_mode){
this.setState({
mode:_mode
})
}.bind(this)}>
</Control>
import
<ReadContent>...</ReadContent>
부분을 가변적으로 만들기 위해 {_article}
로 대체// App.js
render() {
var _title, _desc, _article = null; // _artlcle 변수 선언
// mode가 welcome이나 read면 기존 ReadContent가 _article 자리에 들어감
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>
// mode가 create면 _article에 CreateContent가 들어감
}else if(this.state.mode === 'create'){
_article = <CreateContent title={_title} desc={_desc}></CreateContent>
}
return (
<div className="App">
...
<Control ...>
</Control>
{_article}
</div>
);
}
<article>
<h2>Create</h2>
<form action="/create_process" method="post"
onSubmit={function(e){
e.preventDefault(); // 페이지 전환 방지
}.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>
// App.js
...
}else if(this.state.mode === 'create'){
_article = <CreateContent onSubmit={function(_title, _desc){
console.log(_title, _desc); // 값 잘 들어오나 찍어보기
}.bind(this)}></CreateContent>
}
// CreateConent.js
<form action="/create_process" method="post"
onSubmit={function(e){
e.preventDefault(); // 페이지 전환 방지
this.props.onSubmit( // form(e) - target - name 값(title/desc) - value
e.target.title.value,
e.target.desc.value
);
}.bind(this)}
>
🤦♀️
오... 잘 쓰면 엄청 유용할 거 같고 효율적일 거 같은데 머리가 너무 복잡하다.
계속 정리하고 연습해봐야 언제 어떻게 써야 할지 감이 올 것 같다.
// App.js
constructor(props){
super(props);
this.max_content_id = 3; // max_content_id 선언
...
}
...
}else if(this.state.mode === 'create'){
_article = <CreateContent onSubmit={function(_title, _desc){
this.max_content_id = this.max_content_id + 1; // max_content_id 증가
var _contents = this.state.contents.concat( // concat 함수로 contents에 정보를 추가한 _contents 선언
{id:this.max_content_id, title:_title, desc:_desc}
);
this.setState({
contents:_contents // state의 contents 변경
});
}.bind(this)}></CreateContent>
}
push
var a = [1, 2]
a.push(3);
console.log(a); // [1, 2, 3]
concat
var a = [1, 2]
a.concat(3);
console.log(a); // [1, 2]
👉
push
대신concat
을 사용하면 원본이 남아있으므로 코드가 일관되고 덜 혼란스러움
shouldComponentUpdate
shouldComponentUpdate
함수를 사용하면 자식 컴포넌트에 변경할 내용이 없다면 render
함수를 실행하지 않음// TOC.js
class TOC extends Component {
shouldComponentUpdate(newProps, newState){ // 새롭게 바뀐 값, 기존 값에 접근 가능
console.log('===>TOC render shouldComponentUpdate',
newProps.data // 새로운 값
,this.props.data // 기존 값
); // concat이 아니라 push를 사용하면 기존값 === 새로운 값
if(this.props.data === newProps.data){
return false; // render 호출하지 않음
}
return true; // render 호출
}
render(){
...
}
}
concat
)Array.from()
var a = [1, 2];
var b = Array.from(a); // a로 배열 생성(복제)
console.log(a, b, a===b); // [1, 2] [1, 2] false
👉
push
는Array.from()
을 이용해서 복제한 후에 사용
Object.assign()
var a = {name:'bono'};
var b = Object.assign({}, a); // 빈 객체에 a를 넣어서 새로운 객체 생성
console.log(a, b, a===b); // {name:'bono'} {name:'bono'} false
🙆♀️
shouldComponentUpdate
나immutable
은 성능에 문제가 생길 때 더 알아볼 것!