
React와 연결하기
api
- 고객이 접하는 애플리케이션을 만들기 위해 React 애플리케이션을 만들어보자.
- 만들어질 React애플리케이션이 gc-coffee 스프링부트 애플리케이션의 API를 호출하도록 연결해주자.
리액트 서버에서 스프링부트를 호출할 수 있도록 설정해준다.

- 컨트롤러에 api 패키지를 만들고 그 안에
ProductRestController 클래스를 넣어 꾸며주자.

- 전체 제품을 조회할 수 있는 컨트롤러 메서드를 만들어보자.
@GetMaping의 URL은 api에 v1을 주고 products 복수의 형태로 표현함으로 다건의 제품이 반환된다는 것을 알려줄 수 있다.
- 필요하다면 products에 RequestParam을 사용해서 카테고리별로 조회하게 할수도 있다.

Optional로 카테고리를 받고, map처리를 한다. 카테고리가 존재하면 map의 언더펑션이 동작.
카테고리별 제품, 혹은 모든 제품을 반환한다.


Post

- configuration 패키지를 만들고
MvcConfiguration 클래스를 생성해준다.
WebMvcConfigurer를 이용하면 원하는 Mvc설정을 확장할 수 있다.

addCorsMappings을 통해 cors레지스트리에서 addMapping으로 api에 대한 cors 설정을 할 수 있다.
@Configuration 추가.

React 사용해보기
node.js 다운로드

- 왼쪽 것을 다운로드 받자.
Long Term Support. 오랜 기간 지원한다는 의미로, 안정적이다.
- node.js도 환경변수 설정을 해줘야한다. 자바의 환경변수 설정을 한 것과 비슷하게 하면 된다.
내 PC → 속성 → 고급 시스템 설정 → 환경변수로 들어가준다.
두 가지를 설정해주어야 한다.

NODE_HOME 변수를 생성해준다. 특별히 지정해주지 않는다면 C드라이브의 Program 폴더 안에 위치한다.

- 다음은
Path 변수에서 %NODE_HOME%을 추가해준다.

React



- npx : 노드 패키지를 실행시킬 수 있게 해주는 명령어.
create-react-app을 실행시키며 my-app이라는 폴더를 만들고 해당 폴더에 기본적 설정이 되어 있는 리액트 애플리케이션이 생성됨.


- 빌드 완료.
지정해놓은 경로로 가면 설정해놓은 프로젝트 명으로 생성된 폴더가 있다.



package.json에 가면 "start"명령어를 사용할 수 있는 것을 확인할 수 있다.
package.json은 노드 프로젝트에서 노드 패키지 모듈이라는 것을 알려주는 명세서 같은 것.
start : 리액트 스크립트를 실행시켜, 리액트 애플리케이션을 실행시킨다.


- 리액트 애플리케이션이 실행된 모습.
localhost:3000으로 접속하면 볼 수 있다.
- 리액트 애플리케이션을 만들어보자.
리액트란?
- 프로젝트를 진행하다보면 HTML과 CSS는 퍼블리셔가 제공한다.
디자이너가 이미지 제공 > 이 이미지를 바탕으로 HTML, CSS 작성. > 프론트엔드 개발자가 HTML, CSS를 리액트 애플리케이션으로 전환함.
사용자 인터페이스를 만들기 위한 JavaScript 라이브러리
JS 라이브러리를 이용해서 JS 애플리케이션을 만들 수 있고, 이 JS 애플리케이션이 사용자 인터페이스를 제공한다.
- 대부분 웹 브라우저 인터페이스를 제공하지만, React Native를 이용해서 앱 개발도 가능.
- JSX : 리액트가 개발한 문법으로 개발자가 리액트 코드를 전달하면, 그것을 JS 코드로 변환해서 전달함.
- 리액트는
Element 혹은 Component의 묶음으로 구성된다.
이런 컴포넌트를 정의하고, 이 컴포넌트로 하나의 애플리케이션을 구성하게 된다.
HTML 가져오기

- 이 웹 페이지에서 HTML 파일을 어떻게 저장할까?
- 먼저, 웹 페이지에서
ctrl + s눌러 저장해준다.

- 이런 창이 뜨는데 맨 위의,
웹페이지, HTML만을 체크해준다.
경로를 설정하고 저장을 눌러주면 된다.



- HTML 파일을 인텔리제이에 바로 집어넣으면 HTML 파일의 구조를 알 수 있다.

- 빨간 밑줄을 쳐놓은 부분에서 브라우저를 골라 실행볼수도 있다.
React App
- 리액트 애플리케이션은 src > index.js가 시작지점이 된다.


- APP이라는 애플리케이션을 root에다 구현한다고 볼 수 있다.


- 즉,
App을 바꾸면 화면 구성을 바꿀 수 있다는 뜻.


- App 안의 스크립트를 모두 지우면 리액트 애플리케이션의 웹 화면도 텅 비는 것을 확인할 수 있다.
- 파일이 변경되면 화면을 실시간으로 업데이트해준다.
React 애플리케이션 구성

- sample.html의 body부분을 복사해서
App.js에 넣어준다.



- body를 div로 바꿔주고
ctrl + alt + L을 사용해서 자동으로 포맷팅을 해준다.

- 안닫힌 이미지 태그들을
/를 사용해서 닫아주자.


- hr 태그를 닫아주면 오류를 모두 수정했다고 나오고, 그 순간 React App 페이지가 변한다.

- 지금은 세부설정이 전혀 안되어 있어서 그리 보기 좋은 모습은 아니다.
CSS를 적용해주자.



- sample.html의 style 부분 복사 → App.css에 붙여넣기 → App.js에서 import 설정을 해주면 된다.

- 아까보다는 조금 보기 좋아졌다.
- 더해서, bootstrap을 사용하고 있기 때문에 bootstrap을 추가해주어야 한다.
npm install bootstrap

- 이전에 설치해서 그런지 딱히 출력되는 메시지는 없다.


- bootstrap의 css를 사용할 수 있도록 import를 해줬고, 모양이 얼추 갖춰졌다.
컴포넌트로 쪼개기

- 상품 목록과 Summary의 큰 영역으로 구분된다.
상품 목록 안에는 제품군이 있고 Summary안에는 선택한 아이템들을 보여준다.
- 이들을 컴포넌트로 분리해주자.
ProductList 컴포넌트 만들기
- 리액트에서는 클래스 컴포넌트도 생성할 수 있지만, function컴포넌트로 생성해주자.
일반적으로 JS는 소문자로 시작하지만, 컴포넌트라는 것을 알려주기 위해서 대문자로 생성한다.

- return 값으로 나와야하는 것은 element 코드들.
리액트 컴포넌트는 무조건 하나의 엘리멘트만 리턴되어야 한다.
- 두개를 하나로 묶어 div를 할수도 있지만,
React.Fragment를 사용해보자.





- 상품목록에 해당하는 부분의 코드를
function ProductList에 삽입.
→ function App에서 사라졌기 때문에 리액트 애플리케이션에 출력이 되지 않음.
→ function App의 기존 상품목록 부분에 <ProductList/>추가
→ 상품목록 제대로 출력됨.
- 컴포넌트를 구분한 후 다시 애플리케이션에 출력시키는 일련의 과정.
Summary 컴포넌트 만들기

- Summary 도 마찬가지 방법으로 만들어준다.
Product 컴포넌트 만들기

- Product의 컴포넌트도 만들어주자.
- 여기서 잠깐. Product의 각 값 : 커피콩, Columbia Nariñó, 5000원 등의 정보들이 데이터를 받아 출력된다.
이것은 argument로 전달되는데, 리액트에서는 props에 argument를 객체로 전달해주게 된다.

props를 이용해 코드를 바꿨다.
const 상수를 선언하는 함수로 productName 등을 함수로 선언한 것.
props를 통해 객체, 파라미터 형태로 값을 전달받게 된다.
각 데이터에는 { } 표현식을 사용해서 데이터에 접근하게 된다.

- props에 빈 객체가 들어가기 때문에 값이 비어있다.

- props를 이용해 바꾼 Product 컴포넌트를 이용해 코드를 추가했다.

ProductList props 이용해서 바꾸기
- ProductList 역시 props로 처리해줄수 있다.
JS에서는 객체를 디스트럭쳐 할 수 있다.
function ProductList({ products }) { props 안에 products가 존재한다고 보는 것.
products.map(v => ) 프로덕트만큼 매핑을 해서 전체 프로덕트 안에 있는 배열의 요소만큼 변환하는 코드를 작성할 수 있다.
- 각 변수도 하드코딩 된 값이 아닌
v.의 값으로 변경.
- 디폴트 값을 전달해줘야한다.
- 루프를 돌때는 키를 전달해주어야한다.


- 상품 목록이 비었고, product는 App에서 전달해주어야한다.
App과 ProductList 컴포넌트 연계하기
- App에 상태를 만들어보자.
클래스형 컴포넌트로 만들었을 때는 this.state로 상태에 접근할 수 있다.
함수형 컴포넌트에서는 useState();라는 훅을 이용해야한다.
useState();는 인자가 두개인 배열을 반환한다.
const [product, setProduct] = useState();
두번째는 상태값을 바꾸는 함수, 첫번째는 상태에 접근할 수 있는 변수명.


SummaryItem 컴포넌트 만들고 Summary와 연계하기
- Summary에서 반복되고 있는 부분을 처리하기 위해서
SummaryItem 컴포넌트를 만든다.


- ProductList를 작성한 것과 비슷한 방식으로 만들어주면 된다.

- 추가된 제품들이 사라졌다. 디폴트 값이기 때문.
- 총 금액은 전체 목록 아이템에 price를 곱한 가격이기 때문에 함수를 작성해주자.

- totalPrice 메서드 작성.
reduce함수를 이용해 items에서 prev 값과 curr 값을 받아온다.
prev + (curr.price * curr.count) : 이전 값 + (현재값 * 현재개수).
default값은 0으로 설정