본문 바로가기

React.js

주소록 추가 파트 * Immutability helper 심화 *

이 전 내용에서는 배열이나 오브젝트에 요소들을 지우거나 추가 및 수정하는 작업을

진행하였다면, 이번엔 이를 React.js에 접목시켜서 진행해보도록 하겠습니다.


이번 포스팅에서는 이름이랑 전화번호를 입력하고 버튼을 클릭하게 되면 

해당 내용이 주소록에 추가되는 것을 진행해보도록 하겠습니다.


https://github.com/Haamseongho/React_Study/tree/haams/contact




앞서 진행하였던 코드를 이용하여 진행해보도록 하겠습니다. 

이 전 내용을 모르신다면, 확인 후에 다음 URL을 따라 clone이나 fork뜨길 

권장합니다.




시작 전에 어떤 방식으로 진행될 것인지 먼저 생각하고 코딩해봅시다.



해야할 것


1. 이름이랑 전화번호를 입력할 틀을 만든다.

2. 등록할 버튼을 만든다.

3. 이름이랑 전화번호를 입력할 떄에 입력되는 값들은 유동적이기 때문에 state 값으로 정의한다. 
(input 값의 value를 state 변경 값으로 넘긴다)

4. 버튼을 클릭할 경우 주소록 클래스에 주소록이 추가되도록 함수를 가지고 온다.
(어댑터패턴 + props로 접근)





* 이름이랑 전화번호를 입력할 틀을 만드는 클래스[ ContactCreate ] *



import React from 'react';
import propTypes from 'prop-types';

export default class ContactCreate extends React.Component {


render() {
return (
<div>
<h2>Create Contact</h2>
<p>
<input type="text"
name="name"
placeholder="name"
value={this.state.name}
onChange={this.handleChange}/>
<input type="text"
name="phone"
placeholder="phone"
value={this.state.phone}
onChange={this.handleChange}/>
</p>

<button onClick={this.handleClick}>Create</button>
</div>
)
}
}

rendering 하는 부분에서 다음과 같이 input type으로 name과 phone을 준다.

여기서 중요한 것은 text 타입으로 준 것들의 name을 각각 name과 phone으로

주었다는 것이다.


name을 가지고 state값을 변경할 것이고 그 변경한 값이 value에 들어갈 예정이다.

또한 state 변화된 값을 관리하는 메소드는 handleChange가 될 것이기에 

onChange 함수에 넣어둔 것이다.




constructor(props) {
super(props);
this.state = {
name: "",
phone: "",
};

this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}

// 변동 사항 정리해서 주기
handleChange(e) {
let nextState = {}; // 여러개 인풋 처리 가능
// e.target.name --> 여기 name 은 input 데이터의 name 이므로 (name ,phone) 이 됩니다.
nextState[e.target.name] = e.target.value;
this.setState(nextState);
}

// 파라미터는 비어있음 >> Contact.js 에서 handleCreate 메소드를 여기로 넘겨오기
// 버튼이 클릭되면서 Contact.js의 handleCreate 메소드가 발동되고,
// 발동되면서 해당 내용이 Contact.js의 contactData에 추가되는 것.
handleClick(){
const contact = {
name : this.state.name,
phone : this.state.phone
};

this.props.onCreate(contact);
this.setState({
name : "",
phone : ""
})
}


우선 생성자에는 사용할 state 변수들을 써준다.  input type에 대한 변수들이기에 다음과 같이 초기화를 해준다.




handleChange(e) {
let nextState = {}; // 여러개 인풋 처리 가능
// e.target.name --> 여기 name 은 input 데이터의 name 이므로 (name ,phone) 이 됩니다.
nextState[e.target.name] = e.target.value;
this.setState(nextState);
}



handleChange 함수에서는 name으로 변수를 가지고와서 값을 변화시켜서 value에 꼽는 역할을 한다.


인자로 들어 온 e는 e.target.name 으로 들어오고 이벤트 발생 후 타겟이 되는 name 

즉, 앞서 설명한 input 태그 내의 name이 nextState 배열의 키 값으로 들어간다. 

(다음과 같이 진행하면 변경될 변수들을 여러 개 관리하기 편하다)





또한 이렇게 name을 키로 가지고 온 배열의 각 요소의 값을 input 태그의 value로 넣어준다.


쉽게 설명하자면 

nextState[name] = this.state.name , nextState[phone] = this.state.phone

이런 식이 되는 것이다.





다음과 같이 작업을 하게 되면 입력한 값의 name이 키가 되고 그에 대한 값이

value로 들어가서 input 태그의 값들을 가지고 오는데 해당 값은 

state변수의 값들이다. 



이렇게 키와 값이 정해진 상황에서 버튼 클릭 시 handleClick() 함수를 호출하게 되면,



 handleClick(){
const contact = {
name : this.state.name,
phone : this.state.phone
};

this.props.onCreate(contact);
this.setState({
name : "",
phone : ""
})
}


다음과 같이 state변수인 name과 phone을 변화할 contact의 키 값인 name과 phone으로 들어가게 된다.


여기서 핵심 구문이 나온다. 

결국 변화한 내용을 주소록에 추가해줘야 하는 건데, ContactCreate 클래스에서 Contact 클래스로 값을 넘겨서 추가하려면 결국 props를 이용해야하는데, 


this.props.onCreate(contact);


이런 식으로 ContactCreate의 onCreate함수로 값을 넘겨주는데 , props를 인자를 name과 phone을 키로 받는 json 형태의 값 contact를 같이 넘겨준다. 






이제 Contact클래스에서 ContactCreate 클래스를 랜더링 하는 부분을 찾아가면 된다.

여기서 props 값이 onCreate로 보냈기에 Contact클래스에서도 onCreate로 받는다. 


또한 받는 내용은 함수여야 한다. (onCreate가 함수이기 때문!)



handleCreate(contact) {
this.setState({
contactData: update(this.state.contactData,
{
$push: [contact]
})
})
}

<ContactCreate onCreate={this.handleCreate}/>


다음과 같이 handleCreate함수를 onCreate에 매칭시키는데, handleCreate에서 contact 즉, onCreate함수의 인자인 contact와 동일하게 들어가게 된다.


그에 따라 해당 값을 immutability helper를 이용하여 update 시키는데, 

기존 contactData인 state값을 이제 들어올 contact 값 , 즉 onCreate함수의 

name과 phone이 추가되는 것이다.





추가로 ContactCreate.js 파일에서는 onCreate가 함수임을 밝히기 위해 propTypes를

호출하고, 기존 값 설정인 defaultProps를 통하여 onCreate 함수가 에러가 발생할 때

에러 내용을 정의해주면 더 깔끔한 코드가 완성될 것이다.






ContactCreate.propTypes = {
onCreate : propTypes.func
};

ContactCreate.defaultProps = {
onCreate : () => { console.error("onCreate Not defined")}

};






참고

React.PropTypes 15.5부터는 사용안합니다.
prop-types 모듈 설치하고 import 해야합니다.



https://reactjs.org/docs/typechecking-with-proptypes.html

반응형

'React.js' 카테고리의 다른 글

FLUX 소개  (0) 2018.03.01
keyEvent / ref / LifeCycle  (0) 2018.02.23
Immutability helper  (0) 2018.02.14
Contact * 주소록 심화 *  (0) 2018.02.13
sort / filter를 이용한 검색 소개  (0) 2018.02.06