컴포넌트 Props 으로 전달
리액트에서 프롭스(props) 란 ??
props 란 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법이다.
(props 는 propertis 의 줄임말)
props 는 읽기 전용이라, 자식 컴포넌트에서 직접 수정할 수 없다.
//부모 컴포넌트
function Parent(){
return <Chile name="Alice" age ={25} />;
}
//자식 컴포넌트
function Chile(){
return (
<div>
<h1>
간단히 생각.
props 는 부모에서 자식으로 데이터를 전달
리액트 훅(React Hook)은 함수형 컴포넌트에서도 상태(state)나 생명주기(lifecycle) 메서드 등 클래스형 컴포넌트에서 사용할 수 있는 기능을 제공하는 것입니다. React 16.8 버전부터 추가된 기능으로, 함수형 컴포넌트에서 상태 관리와 생명주기 관련 로직을 더 쉽게 작성할 수 있게 해줍니다.
기존에는 함수형 컴포넌트에서 상태를 관리하기 위해서 useState를 사용하고, 생명주기 관련 로직을 작성하기 위해서는 useEffect 등의 함수를 사용해야 했습니다. 하지만 이러한 방법은 상태나 생명주기 메서드가 많아질수록 코드 의 복잡도가 높아지고 유지보수도 어려워졌습니다.
리액트 훅을 이용하면, useState 훅으로 상태를 관리하고 useEffect 훅으로 생명주기 관련 로직을 작성할 수 있습니다. 또한, 커스텀 훅(custom hook)을 만들어서 로직을 재사용할 수 있도록 해줍니다. 예를 들어, 여러 컴포넌트에 서 공통으로 사용하는 로직을 하나의 커스텀 훅으로 만들어서 사용할 수 있습니다.
import React, { useState } from 'react';
const Counter = () => {
const [value, setValue] = useState(0);
return (
<div>
<p>
현재 카운터 값은 <b>{value}</b> 입니다.
</p>
<button onClick={() => setValue(value + 1)}>+1</button>
<button onClick={() => setValue(value - 1)}>-1</button>
</div>
);
};
UseState 를 변경하는 코드를 간단히 작성해보았다.
버튼을 클릭할 시 value 값을 증가시키거나 감소시키는 함수를 만들어서 사용한다.
리액트 훅의 종류
useState: 상태(state)를 관리하기 위해 사용됩니다. useEffect: 렌더링 직후에 실행되며, 컴포넌트의 부수 효과(side effects)를 처리하기 위해 사용됩니다. useContext: 전역 데이터를 관리하기 위해 사용됩니다. useReducer: 상태(state)를 관리하기 위해 사용됩니다. useState보다 복잡한 로직에서 사용됩니다. useCallback: 함수를 캐싱하기 위해 사용됩니다. useMemo: 값을 캐싱하기 위해 사용됩니다. useRef: 컴포넌트 내부에서 참조(reference) 값을 저장하기 위해 사용됩니다. useImperativeHandle: useRef와 함께 사용되며, 부모 컴포넌트에서 자식 컴포넌트의 메서드를 호출하기 위해 사용됩니다. useLayoutEffect: useEffect와 비슷한 역할을 하지만, 렌더링 직후 DOM 노드의 크기나 위치 등을 변경할 때 사용됩니다. useDebugValue: 커스텀 훅에서 사용됩니다. 디버깅에 유용합니다.
useMemo: 값을 캐싱하기 위해 사용됩니다.????
useMemo는 계산된 값을 캐싱하여, 동일한 계산이 반복될 때 계산 시간을 절약하는 것을 말합니다.
예를 들어, 리액트 컴포넌트에서 특정 값을 계산하고, 이 값이 변경되지 않았을 때 이전 값으로 재사용할 수 있습니다. 이때 useMemo를 사용하면 계산된 값을 캐싱하여 다음 렌더링에서 동일한 계산을 다시 수행하지 않고 이전 값을 재사용할 수 있습니다.
이를 통해 애플리케이션의 성능을 최적화할 수 있습니다. 만약 값이 변경될 가능성이 있는 경우, 캐시된 값을 다시 계산하고 갱신해주어야 합니다.
UseEffect
//상태값이 바뀔 때마다 동작 , 기본적 비동기처리
즉 , 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 리액트 hook 이다.
사용법
import React, { useEffect } from "react";
useEffect(() =>{
//수행할 함수
})
깃허브에서 react 프로젝트 배포하기
1. gh-pages 패키지 다운로드
npm install gh-pages --save-dev
현재 위치가 react project 파일들이 있는 폴더인지 확인한 후 설치한다.
2. package.json 파일에 정보 입력
homepage property 추가
"homepage": "https://{github id}.github.io/{repository 이름}"
script property에 predeploy, deploy 추가
"scripts": {
...
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}
그리고 그대로 원래 하던대로 add commit push
그리고 npm run deploy 하면
https://codingapple.com/unit/react-build-deploy-github-pages/
참고 . 리액트 깃허브 배포
리액트와 스프링부트 연동하기
연동하면 좋은점
백엔드 코드에서는 더 이상 뷰 페이지를 만들 필요가 없음
CORS(Cross-Origin Resource Sharing)
한국어로 직역하면 '교차 출처 리소스 공유'라고 해석할 수 있다. 여기서 '교차 출처(Cross-Origin)'이란 '다른 출처'를 의미한다.
해석을 해보면 Cross-Origin의 Resrouce를 공유하는 정책이라고 볼 수 있다.
즉, CORS란 도메인이 다른 서버끼리 리소스를 주고 받을 때 보안을 위해 설정된 정책이라고 생각하면 된다.
예를 들어, 웹 사이트 A가 API 서버 B에서 데이터를 가져오려 할 때,
API 서버 B에서 CORS 허용 설정이 되어 있지 않으면 웹 브라우저에서 API 접근이 거부될 수 있다.
또한 프론트엔드와 백엔드가 협업하면서 각자 따로 서버를 띄우게 되었을 경우도 마찬가지다. 서로 다른 React 서버(3000 포트)와 Springboot(8080 포트) 서버가 리소스를 주고 받으려 한다면 포트가 달라 서로 다른 출처로 판단되어 CORS 위반 에러가 발생한다.
뭐 대충 주인이 허가 안해주면 그 서버에 접근 못하게 하는거임
import { useState,useEffect } from "react"
import axios from "axios"
const Param = ()=>{
const handleParam1 = (e)=>{
axios.get(`http://localhost:8095/param/01`,
{params:{name:'홍길동'},
headers:{'Content-Type':'application/json'}}) //url을 전달 ? //백틱
.then(resp=>{console.log(resp);})
.catch(err=>{console.log(err);})
}
const handleParam2 = (e)=>{
axios.get(`http://localhost:8095/param/02/${'박대해'}/${150}/${'서울'}`,
{params:{name:'홍길동'},
headers:{'Content-Type':'application/json'}}) //url을 전달 ? //백틱
.then(resp=>{console.log(resp);})
.catch(err=>{console.log(err);})
}
return (
<div>
<button onClick={handleParam1}> GET /param01 박대해</button>
<hr />
<button onClick={handleParam2}>GET /param02/02/박대해/1515/서울</button>
</div>
)
}
export default Param
버튼으로 비동기방식으로 요청을 보내면
package com.example.app.controller;
import com.example.app.domain.dto.PersonDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.awt.*;
import java.util.LinkedHashMap;
import java.util.Map;
@RestController
@Slf4j
@RequestMapping("/param")
@CrossOrigin(origins={"<http://localhost:3000>","<http://127.0.0.1:3000>"}) //허용할 오리진명 명시
public class ParamController {
@RequestMapping(value = "/01",method = {RequestMethod.GET,RequestMethod.POST},produces = MediaType.APPLICATION_JSON_VALUE) //consume 을 쓰면 get에 쓰는거라 없앰 왜 ? 둘다 JSON 으로 그냥 해놓으면 되는거아님 ? 흠..
public ResponseEntity< Map<String,Object> > param01(@RequestParam(value = "name",required = false)String name){
Map<String,Object> map = new LinkedHashMap<>();
log.info("GET /param/01..!"+name);
map.put("name",name);
map.put("status","success");
return new ResponseEntity<>(map, HttpStatus.OK);
}
@RequestMapping(value = "/02/{name}/{age}/{addr}",method = {RequestMethod.GET,RequestMethod.POST},produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String,Object>> param02(PersonDto personDto){
Map<String,Object> map = new LinkedHashMap<>();
map.put("name",personDto.getName());
map.put("age",personDto.getAge());
map.put("addr",personDto.getAddr());
log.info("GET /param/02..!"+personDto);
return personDto==null?new ResponseEntity<>(null,HttpStatus.EXPECTATION_FAILED) : new ResponseEntity<>(map,HttpStatus.OK); //처리 결과에 따라 리스폰스를 다르게 반환 , personDto 가 null 이라면
}
@RequestMapping(value = "/03",method = {RequestMethod.GET,RequestMethod.POST},consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String,Object>> param03(@RequestBody PersonDto personDto){ //requestbody 로 해서 json 타입으로 보내도 괜찮음
Map<String,Object> map = new LinkedHashMap<>();
map.put("name",personDto.getName());
map.put("age",personDto.getAge());
map.put("addr",personDto.getAddr());
map.put("status","success");
log.info("GET /param/03..!" + personDto);
if(personDto == null){
log.info("널이다");
}else{
log.info("널 아님 ~~");
}
return personDto==null?new ResponseEntity<>(null,HttpStatus.EXPECTATION_FAILED) : new ResponseEntity<>(map,HttpStatus.OK);
}
}
컨트롤러에서 백엔드 로직을 처리한다.
근데 여기서 Controller 에서 CrossOrigin 어노테이션을 명시해주지 않으면 Cors 문제가 생긴다.
이처럼 콘솔에서 cors 에러가 뜨게 된다.
'Developer Note > 국비과정 수업내용 정리&저장' 카테고리의 다른 글
24년 12월 16일 (1) | 2024.12.18 |
---|---|
24년 12월 13일 (2) | 2024.12.18 |
24년 12월 10일 (0) | 2024.12.18 |
24년 12월 9일 (1) | 2024.12.18 |
24년 12월 6일 (2) | 2024.12.15 |