0%

리액트 정리 - 1

Goal

리액트를 이용해 전화번호부 구현한 내용 정리.

Prologue

작년 하반기에 리액트에 관심이 생겨 팀내 스터디를 만들어 올초 1월까지 학습하였고, 학습한 내용을 소화할겸 전화번호부를 구현해 보았다. 본 글은 1,2편으로 나누어 작성할 것이고 1편은 리액트만을 이용해 구현한 부분까지, 2편은 리덕스를 적용한 내용에 대해 포스팅할 예정이다.

Mockup

아래 그림은 구현할 전화번호부의 모습이다.
Mockup

상단의 검색바에서 사람을 검색할 수 있고, 추가버튼을 눌러 전화번호부에 추가를 할 수 있다.
좌측 하단에는 검색된 사람의 리스트를 나열하며, x버튼을 눌러 전화번호부에서 삭제를 할 수 있다.
전화번호부 리스트의 사람을 선택하면 우측에 상세정보를 나타낸다.

Component

리액트로 애플리케이션 인터페이스를 설계할때 여러가지 컴포넌트로 구성할 수 있다.
아래의 그림은 먼저 그린 목업에 내가 구현할 방식으로 컴포넌트를 나눈 모습이다.
Component

  • SearchBar: 검색바와 추가버튼
  • PhoneBookList: 전화번호 리스트
  • PhoneBook: 개별 전화번호와 삭제버튼
  • PhoneBookDetail: 전화번호 상세
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// App.js
import React, { Component } from 'react';
import SearchBar from './components/SearchBar';
import PhoneBookList from './components/PhoneBookList';
import PhoneBookDetail from './components/PhoneBookDetail';

class App extends Component {
render() {
return (
<div>
<SearchBar/>
<PhoneBookList/>
<PhoneDetail/>
<\/div>
);
}
}
export default App;

State

리액트 컴포넌트 내부에서 읽고 업데이트 할 수 있는 값을 지정하기위해 State를 사용한다.
State는 컴포넌트 내부에서 this.state 로 접근 가능하며, 상태변경을 위해선 반드시 this.setState()로만 변경해야 한다.

  • allList: 전화번호부 전체리스트
  • selectedList: 전화번호부 검색리스트(검색용)
  • selectedPhoneBook: 상세보기 대상 전화번호부
  • inputPhoneBook: 검색 입력값
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class App extends Component {
state = {
allList: phoneList,
selectedList: phoneList,
selectedPhoneBook: '',
inputPhoneBook: ''
}

render() {
return (
<div>
<SearchBar/>
<PhoneBookList/>
<PhoneDetail/>
<\/div>
);
}
}
export default App;

Props

props는 properties를 줄인 표현으로 컴포넌트 속성을 사용할 때 사용하는 요소이며 부모 컴포넌트(해당 컴포넌트를 불러와 사용하는 컴포넌트)에서만 설정 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// App.js
class App extends Component {
state = {
allList: phoneList,
selectedList: phoneList,
selectedPhoneBook: '',
inputPhoneBook: ''
}

render() {
const { inputPhoneBook, selectedList, selectedPhoneBook } = this.state;
return (
<div>
// 부모 컴포넌트에서 html속성을 넣듯이 props를 넘길수 있다.
<SearchBar inputPhoneBook={inputPhoneBook} />
<PhoneBookList phoneBookList={selectedList}/>
<PhoneDetail phoneBook={selectedPhoneBook}/>
<\/div>
);
}
}
export default App;

// SearchBar.js
export default class SearchBar extends Component {
render() {
return (
<div>
// 자녀 컴포넌트에서 this.props로 넘겨받은 props값을 접근할 수 있다.
<input type="text" value={this.props.inputPhoneBook} placeholder="Search.."/>
<div>
<button type="button">추가<\/button>
<\/div>
<\/div>
)
}
}

Event Handling

리액트의 이벤트 시스템은 html 이벤트와 사용법이 매우 비슷하지만 주의할 점이 있다.

  • 이벤트 이름은 camelCase로 작성한다.(예: onclick => onClick, onkeyup => onKeyUp)
  • 이벤트에 실행할 자바스크립트 코드를 전달하는것이 아니라, 함수 형태의 값을 전달한다.
  • DOM 요소에만 이벤트를 설정할 수 있다.(내가 만든 컴포넌트는 이벤트를 설정 할 수 없다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// App.js
class App extends Component {
(...)
// 이벤트는 함수로 넘겨야 한다.
handleSelectedList = (e) => {
this.setState({
selectedList: this.state.allList.filter(phonebook => phonebook.name.search(e.target.value) !== -1),
inputPhoneBook: e.target.value
});
}

addPhoneBook = () => {
const { allList, inputPhoneBook } = this.state;
const newPhoneBook = {
id: this.id++,
name: inputPhoneBook,
phonenumber: '',
address: ''
}

this.setState( {
allList: [...allList, newPhoneBook],
selectedPhoneBook: newPhoneBook,
selectedList: [newPhoneBook]
})
}

render() {
const { inputPhoneBook, selectedList, selectedPhoneBook } = this.state;
const { handleSelectedList, addPhoneBook } = this;
return (
<div>
<SearchBar inputPhoneBook={inputPhoneBook} handleSelectedList = {handleSelectedList} addPhoneBook = {addPhoneBook} />
<PhoneBookList phoneBookList={selectedList}/>
<PhoneDetail phoneBook={selectedPhoneBook}/>
<\/div>
);
}
}
export default App;

// SearchBar.js
export default class SearchBar extends Component {
render() {
const { inputPhoneBook, handleSelectedList, addPhoneBook } = this.props;
return (
<div>
<input type="text" onChange={handleSelectedList} value={inputPhoneBook} placeholder="Search.."/>
<div>
<button type="button" onClick={addPhoneBook}>추가<\/button>
<\/div>
<\/div>
)
}
}

Conclusion

순수 리액트만으로 전화번호부 구현 방법에 대해 살펴보았다.
구현에 대한 전체소스는 여기 에서 확인 할 수 있다.

Reference : 리액트를 다루는 기술