이번 게시글에선 Map 을 사용해 데이터를 직접 랜더링해보는 과정을 볼 것이다.
이전 게시글의 소스를 기반으로 수정하여 사용했음을 참고.
이번엔 직원이름, 연차를 입력받아 등록하는 화면을 만들고자 한다.
사용하게 될 js 파일을 먼저 요약정리부터 해본다면 아래와 같다.
App.js - 메인컴포넌트. UserInput.js ( 입력폼 ) 과 UserProfileList.js ( UserProfile Data List ) 를 호출.
UserInput.js - 신규 유저를 등록하는 입력폼 컴포넌트.
UserProfileList.js - 유저의 정보 ( JSX ) 를 가지고 있는 List 컴포넌트.
UserProfile.js - 각각 개별의 유저 정보 컴포넌트.
먼저 메인 컴포넌트인 App.js 부터 살펴보자
App.js
import { render } from '@testing-library/react';
import React, { Component } from 'react';
import './App.css';
import UserInput from './UserInput';
import UserProfileList from './UserProfileList';
class App extends Component {
//Map 에서 사용 될 고유성을 가리기 위한 key
id = 0;
state = {
userInfo: []
}
loginUserHistory = (data) => {
const {userInfo} = this.state;
//userInfo 배열에 UserInput 컴포넌트, UserProfileList 컴포넌트에서 return 받은 data 와 id 를 넣는다
this.setState({
userInfo: userInfo.concat({
id: this.id++, ...data
})
})
}
render() {
return (
<div>
{/* UserInput 컴포넌트 호출, return 받은 후 loginUserHistory 함수 호출 */}
<UserInput onCreate={this.loginUserHistory} />
{/* UserProfileList 컴포넌트 호출 */}
<UserProfileList data={this.state.userInfo} />
</div>
);
}
}
export default App;
간단하게 사이클만 설명하자면 render 함수에서 UserInput.js 컴포넌트를 호출했다.
그렇다는건 UserInput 에서 return 해주는 데이터가 현 컴포넌트 ( App.js ) 로 올테고,
이 데이터를 loginUserHistory 함수에서 userInfo 배열안에 집어넣어준다.
그 후 render 함수에서 UserProfileList 를 호출하는데 이 때 parameter 로 현 state 에 있는 userInfo 를 보낸다.
밑에서 나오겠지만 먼저 앞서 말하자면 userInfo 배열 안의 data 는 Map 이 들어가있다.
컴포넌트를 하나하나 살펴보자.
render 함수에서 호출한 UserInput.js 컴포넌트는 다음과 같다.
UserInput.js
import React, {Component} from 'react';
class UserInput extends Component {
//state 에 userName, year 초기화
state = {
userName: '',
year: ''
}
inputChange = (e) => {
this.setState({
//key : value
[e.target.name]: e.target.value
})
}
loginUser = (e) => {
//submit 후 reload 방지
e.preventDefault();
//부모에서 넘어온 onCreate 호출해 state 전달
this.props.onCreate(this.state);
//state 초기화
this.setState({
userName: '',
year: ''
})
}
render() {
return (
<form onSubmit={this.loginUser}>
<input type='text' name='userName' placeholder='이름을 입력하세요' onChange={this.inputChange} value={this.state.userName}/>
<input type='text' name='year' placeholder='연차를 입력하세요' onChange={this.inputChange} value={this.state.year}/>
<button type='submit'>등록</button>
</form>
)
}
}
export default UserInput;
UserInput.js 컴포넌트는 이전 게시글의 User.js 컴포넌트와 별 다를게 없다. 파일명만 바뀌었을 뿐이다.
UserProfileList.js
import React, { Component } from 'react';
import UserProfile from './UserProfile';
class UserProfileList extends Component {
static defaultProps = {
data: []
}
render() {
//App.js 컴포넌트에서 호출할 때 넘겨준 data 들어감.
const { data } = this.props;
//data 배열을 map 으로 변환해준다. 이 때 UserProfile.js 컴포넌트를 호출.
const userInfoMap = data.map(
info => (<UserProfile key={info.id} info={info}/>)
);
return (
<div>
{/* 위에 변환된 userInfoMap 을 return 해준다 */}
{userInfoMap}
</div>
);
}
}
export default UserProfileList;
주석으로 이미 설명했지만 다시 한번 더 풀어 보자면,
this.props 는 App.js 에서 현 컴포넌트를 호출하며 넘겨준 배열이다.
이 배열을 map 으로 변환하는 과정인데
const userInfoMap = data.map(
info => (<UserProfile key={info.id} info={info}/>)
);
UserProfile.js 컴포넌트를 호출하는데 이 때 parameter 로 key : info.id 와 info : info 를 보낸다.
그럼 호출되어지는 UserProfile.js 컴포넌트 입장에서는 info.id 와 info 를 사용하게 될 것이다.
UserProfile.js 컴포넌트에서 이런 저런 일을 한 후 현 컴포넌트 ( UserProfileList.js ) 로 값을 return 해주고,
이 값은 map 으로 변환되어 userInfoMap 에 넣어진 뒤 자신을 호출한 App.js 컴포넌트로 return 해주는 로직이다.
그럼 다음은 배열을 맵으로 변환하는 과정에서 호출한 UserProfile.js 컴포넌트를 살펴보자.
UserProfile.js
import React, { Component } from 'react';
class UserProfile extends Component {
//신규 유저를 등록하기 전 최초 화면이 로딩될 때도 호출이 되는데 이 때는 data 가 존재하지 않음. default 초기화 선언.
static defaultProps = {
info: {
userName: '이름',
year: 0,
id: 0
}
}
//연차에 따라 직급을 return 해주는 함수 ( 연차 기준은 임의로 정한 조건임 )
checkYear = (year) => {
if(year == 0) {
return '신입';
}
if(year == 1) {
return '사원';
}
if(year == 2) {
return '대리';
}
if(year >= 3 && year <= 4) {
return '과장';
}
if(year >= 5 && year <= 6) {
return '차장';
}
if(year >= 7 && year <= 10) {
return '부장';
}
if(year > 10) {
return '사장';
}
}
render() {
//https://velopert.com/3636 블로그를 참고해 공부하는 중인데 만들어놓으신 style 적용했음
const style = {
border: '1px solid black',
padding: '8px',
margin: '8px'
};
//userName, year, id 각자 UserProfileList.js 컴포넌트에서 넘어온 데이터 할당
const { userName, year, id } = this.props.info;
return (
<div style={style}>
<div><b>이름 : {userName}</b></div>
<div>연차 : {year}년</div>
<div>직급 : {this.checkYear(year)}</div>
</div>
);
}
}
export default UserProfile;
이 컴포넌트는 블록별로 상세하게 살펴보도록 하자.
위에서 언급했 듯 UserProfileList.js 컴포넌트에서 key : info.id 와 info : info 를 보내주었다.
UserProfile.js 컴포넌트가 위 쪽에 아래와 같이 defaultProps 로 info 를 선언해 놓았기에,
static defaultProps = {
info: {
userName: '이름',
year: 0,
id: 0
}
}
this.props.info 만 해도 현 컴포넌트에서 선언한 info 의 userName, year, id 는
parameter 로 넘어온 userName, year, id 와 일치하니
바인드되어 userName, year, id 에 값이 들어가게 되는 것이다.
const { userName, year, id } = this.props.info;
그 후 return 하고자 하는 JSX 문법 내에서 this.checkYear 함수를 호출했고,
year 의 값에 따라 직위를 return 해 완성된 JSX 문법으로 return 해주게 되는 것이다.
checkYear = (year) => {
if(year == 0) {
return '신입';
}
if(year == 1) {
return '사원';
}
if(year == 2) {
return '대리';
}
if(year >= 3 && year <= 4) {
return '과장';
}
if(year >= 5 && year <= 6) {
return '차장';
}
if(year >= 7 && year <= 10) {
return '부장';
}
if(year > 10) {
return '사장';
}
}
.
.
.
...
return (
<div style={style}>
<div><b>이름 : {userName}</b></div>
<div>연차 : {year}년</div>
<div>직급 : {this.checkYear(year)}</div>
</div>
);
실행화면
이름과 연차를 입력 후 버튼을 클릭하면 아래에 새로운 data 가 생길 것이다.
'Coding Story > REACT' 카테고리의 다른 글
[ React ] 리액트 함수형 프로그래밍 (0) | 2020.10.21 |
---|---|
[ React ] 리액트 전개 연산자 ? (0) | 2020.10.21 |
[ React ] 리액트 Input Form 상태 관리, 배열 관리 (0) | 2020.10.21 |
[ React ] 리액트 동적 데이터 state (0) | 2020.10.21 |
[ React ] 리액트 정적 데이터 pops (0) | 2020.10.21 |