앞서 만든 계산기 코드를 깔끔하게 줄여 고도화를 해보았다.
계산기의 버튼 영역 구조를 ul li button 태그로 작성을 하였는데 이러한 반복되는 영역을
컴포넌트화하여 간결한 코드로 작성해보자.
이전에는 아래와 같이 src 폴더에 components 폴더와 pages 폴더를 만들고, pages폴더 속에 Main/Home 폴더만
작성하였다면,
1) components폴더에 Button 폴더를 생성하여 Button 컴포넌트를 생성해보자
2) 제일 먼저 해야 할일은 App.js 에서 설정해야 한다.
- import React from 'react'
- import './App.css'
- import Home from './pages/Home' >> Home 폴더에서 Home 함수를 가져온다.
- const App = () => {
return <Home />
}
- export default App
>> Home함수 값을 내보내는 함수인 App 을 생성하여 App을 내보낸다.
이렇게 설정한 App.js 안에 들어갈 항목들은 아래와 같다.
3) 메인 페이지인 Home 폴더의 jsx 파일에 Button컴포넌트를 연결한다.
그리고 ul li 태그 속에
Button 태그 대신 <Button />을 작성하여
데이터를 가져온다.
Button 컴포넌트에 작성된 코드 그대로 브라우저에 보이기 때문에
컴포넌트를 분리하기 전의 Button 태그에 작성한 className과 onClick 그리고 button태그 속에 작성된 데이터 (text)를
<button className='item-button' onClick={ ( )=>{ this.onClick('1') } }>1</button>
Button 컴포넌트에 코드로 옮겨준다.
Button 컴포넌트 안에 작성된 Button 함수의 parameter에 필요한 속성들을 작성해주어야 하는데
이는 Home 컴포넌트에 있는 데이터를 가져와서 넣는 것이므로 {}안에 작성해야 한다.
****컴포넌트 간 통신하는 방법 : 받는 쪽에서 컴포넌트 데이터 받기****
- 보내는 쪽 (Button 컴포넌트)
보내는 쪽은 Button className='item-button' onClick={this.onClick} text={data}으로 보낸다.
함수형 컴포넌트의 parameter 부분에 객테 ( { } )를 만들어서 받을 데이터를 넣어주어야 한다.
- 받는 쪽 (Home 컴포넌트)
Home 컴포넌트에소 Button 컴포넌트의 parameter에 받을 데이터들을 보내주어야 한다.
데이터들은 ClassName, onClick, text 이다.
(리터럴 string 2개와 함수1개 : string = className, text / function = onClick)
<button className='item-button' onClick={ ( )=>{ this.onClick('1') } }>1</button> 이므로..
이러한 동작을 props 라고 한다.
**props 는 컴포넌트에서 사용할 데이터 중 변동되지 않는 데이터를 다룰 때 사용되는데 parent(부모) 컴포넌트에서
child(자식) 컴포넌트로 데이터를 전할 때 props 가 사용된다.
위에 사용될 데이터는 state안에 배열로 만들어놓았다.
함수형 컴포넌트일 때는 상태를 사용하지 못한다.
상태를 추가하려면, 클래스 컴포넌트로 변경을 해야한다.
여기서는 Home이 부모, Button이 자식이다.
4) 버튼을 반복문을 통해 만들기
계산기를 보면 이런 형태로 되어있는데
각각 한 행으로 총 5행으로 보고 (빨간박스가 각각 ul태그)
body 구조를 총 ul 5개, ul 안에 총 4개의 li가 있도록 만들었다.
(li안에는 button태그 즉, button 컴포넌트가 포함되어 있다.)
Button 컴포넌트는 onClick과 text를 제외하고 모두 동일한 구조와 속성을 가지고 있기 때문에
반복문을 만들어 코드를 더 간결하게 만들 수 있다.
Button을 반복하여 만들어줄 반복문과 버튼마다 다른 데이터를 담을 배열이 필요하다.
createButtonElements() 함수와 state안에 buttonArray 배열을 만든다.
1. buttonArray 배열
계산기에 필요한 5개의 줄과
그 속에 담을 각각 4개의 버튼(데이터)를 배열로 작성해준다.
2. createButtonElements() 함수
createButtonElements 함수의 return 구문에 반복되어야 할 코드들을 넣어준다.
<div className='button-layer'> 태그 속의 ul 태그 잘라오기
한줄을 의미하는 ul태그와 그 안의 코드들을 작성한다. !3
createButtonElements 함수의 parameter에 작성된 arr은 한줄 이라는 뜻으로 사용된다. (배열 한개)
어떤 배열인지 알기 위해 createButtonElements 함수의 parameter에 arr(배열하나)를 넣어
한 배열만 함수의 return 구문이 반환되도록 한 것이다.
{ this.createButtonElements( this.state.buttonArray[0] ) }
**map 함수: ul 함수 즉 한 줄(row)에서 li태그가 버튼의 수만큼 반복되어야 하기 때문에 map함수를 이용한다.
------------------- map 함수란? ----------------------
map 함수는 배열안에 있는 요소들을 모두 순회하여
배열의 크기(요소의 갯수) 만큼 return구문에 작성한 내용으로 바뀌어 반환한다.
map은 배열의 크기는 동일한데 값을 바꾸어주고 싶을 때 사용한다.
예를 들어
[1,2,3].map((data,index)) => {
return data +1
});
//[2,3,4]로 출력한다.
1이 다 돌아가면 2가 실행이 되고 2가 다 돌아가면 3이 실행이 된다.
배열의 하나씩 함수가 돌아간다.
map의 parameter에는 함수를 받는다.
첫번째 인자: 값, 두번째 인자: 순서를 뜻한다. (data,index)
-----------------------------------------------------
이 함수를 이용해 아까 작성했던 buttonArray를 순회하도록 만들어야 한다.
data는 배열안에 있는 요소, index는 배열의 순서를 의미한다.
li태그가 반복되어야 하기 때문에 key={index}를 반드시 작성하여 배열의 순서를 인지할 수 있도록 해야한다!
key는 고유번호를 의미한다.
map함수가 순회하여 빨간 박스안의 코드처럼 요소들의 내용이 바뀌게 된다.
위에 작성된 text={data}는 buttonAraay 배열에 작성된 데이터들을 가져오게 된다.
onClick={this.onClick}은
Button컴포넌트에서 onClick을 가져온다는 의미이다.
button 태그에 있는 onClick(text)의 text는
위에서 작성한 text={data} 이다.
즉, buttonArray의 요소에 작성된 text가
onClick의 parameter로 들어가 있는 것.
이 onClick의 parameter로 Home 컴포넌트에 있는
onClick 함수(value가 =이면 계산되는 함수)를 실행하는 것이다.
createButtonElements() 함수가 5번 반복되어야 하기 때문에 Home 컴포넌트의 return구문 중
버튼 영역안에 createButtonElements()데이터를 가져와 실행시키는 코드를 작성해준다.
buttonArray의 0번째 요소부터 4번째까지의 요소를 한번씩 불러와 createButtonElements() 로 실행하여 버튼을 만든다.
이렇게
Button 컴포넌트를 만들고 class형 컴포넌트, map 함수, 배열을 통해 반복적인 것을 담고 데이터를 보내주어
반복되는 코드를 간단하게 만들어 계산기를 만들 수 있다.
'개발 이야기' 카테고리의 다른 글
[Router] Module 사용하기/transition 주기 (0) | 2020.01.09 |
---|---|
[리액트] 날씨 API 가져오기 (0) | 2020.01.05 |
[리액트] 계산기 만들기1 (0) | 2019.12.17 |
[클래스컴포넌트] TodoList 만들기를 통한 리액트 알아보기 (0) | 2019.12.07 |
[리액트] 이론 2_이해하기 (0) | 2019.12.03 |