25.05.22 (목) 68일차 React

허배령·2025년 5월 22일

괴발개발 TIL

목록 보기
52/54

Context API 란?

  • React 컴포넌트 트리 전체에서 데이터를 공유할 수 있는 방법을 제공
  • 부모자식간 관계가 중첩된 구조에서 데이터를 전달하는데 있어 불필요한
    props drilling (상태 내리꽂기)을 방지함
  • 사용하기 위해서 useContext hook 필요함
  • React에 기본적으로 내장됨

Context API를 사용하려면 객체가 필요
React.createContext() : Context 객체를 생성 시 사용하는 함수

  • Context : react에서 컴포넌트 계층 구조를 통해 데이터를 효율적으로 전달하기 위한 메커니즘 (작동원리 / 방식)
  • Provider : 데이터를 제공 (Exam6)
  • Consumer : 데이터를 소비 (Child3)
  • Context.Provider : 하위 컴포넌트에게 데이터를 전달할 때 (제공할 때) 사용
import { createContext, useContext, useState } from "react";

const UserContext = createContext(); // import 해줘야 함

// 부모 컴포넌트
const Exam6 = () => {
  const [user, setUser] = useState("홍길동");

  // Context.Provider : 하위 컴포넌트에게 데이터를 전달할 때 (제공할 때) 사용
  return (
    <UserContext.Provider value={{ user, test: "test값 입니다." }}>
      <h1>부모 : 부모가 가진 상태 값 {user}</h1>
      <Child1 />
    </UserContext.Provider>
  );
};

const Child1 = () => {
  return (
    <>
      <h1>Child1</h1>
      <Child2 />
    </>
  );
};

const Child2 = () => {
  const contextValue = useContext(UserContext);
  return (
    <>
      <h1>
        Child2 : {contextValue.user} / {contextValue.test}
      </h1>
      <Child3 />
    </>
  );
};

const Child3 = () => {
  // Exam6가 가진 user 상태 값을 사용하고 싶다!

  const contextValue = useContext(UserContext);
  // Context로 등록된 객체 중 이름이 UserContext를 꺼내어
  return (
    <>
      <h1>
        Child3 : {contextValue.user} / {contextValue.test}
      </h1>
    </>
  );
};

export default Exam6;
<UserContext.Provider value={ {user, test : "test값 입니다."}}>

1개의 데이터는 value={ }, 여러개는 k:v 꼴로 {} 추가해서 나열하기

React(프론트 : 클라이언트) - JS 요청 (비동기)
SpringBoot(백엔드 : 서버) - DB 조회 후 반환

CORS (Cross Origin Resource Sharing) Error

Origin(url) :
http://localhost:5173
http://localhost:80
서로 포트가 달라도 서로 사용하도록 허락 (어노테이션으로)

@CrossOrigin : Spring에서 제공하는 어노테이션으로 CORS 설정을 위해 사용됨

CORS (Cross-Origin Resource Sharing)
-> 클라이언트와 서버가 서로 다른 출처(origin)에서 요청을 주고 받을 때 발생하는 보안 정책
-> 브라우저에서는 기본적으로 다른 출처(도메인, 프로토콜, 포트)의 요청을 차단함

server

@CrossOrigin(origins = "http://localhost:5173") // 이 http를 허용함
@RestController
public class MyAppController {
	
	@GetMapping("getPortNumber")
	public List<String> getPortNumber() {
		return Arrays.asList("서버포트는 80", "클라이언트 포트는 5173");
	}
	
	@PostMapping("getUserInfo")
	public String getUserInfo(@RequestBody Map<String, Object> map) {
		
		// message 리턴
		// 만약에 요청데이터 중 name값이 홍길동이고, age값이 20이면
		// "홍길동 님은 20세 입니다" 리턴
		// 같지 않다면 "데이터가 없습니다" 리턴
		
		System.out.println(map.get("name"));
		System.out.println(map.get("age"));
		
		String message = "데이터가 없습니다.";
		
		if(map.get("name").equals("홍길동") && map.get("age").equals("20")) {
			message = "홍길동 님은 20세 입니다.";
		} 
		
		return message;
	}
}

client

import { useState } from "react";

const Exam7 = () => {
  const [portMsg, setPortMsg] = useState(null); // 비동기 요청할 때 띄우려고
  const [userMsg, setUserMsg] = useState(""); // String 형태라 ""

  const getPortNumber = () => {
    fetch("http://localhost/getPortNumber") // 오리진이 달라서 http://
      .then((res) => res.json()) // List로 넘어와서
      .then((data) => {
        setPortMsg(data);
      });
  };
  const getUserInfo = () => {
    fetch("http://localhost/getUserInfo", {
      method: "post",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: "홍길동", age: "20" }),
    })
      .then((res) => res.text())
      .then((data) => setUserMsg(data));
  };

  return (
    <div>
      <p>1. 서버로부터 응답 받은 (GET)</p>
      <button onClick={getPortNumber}>GET 요청 보내기</button>
      <ul>
        {portMsg?.map((msg, idx) => (
          <li key={idx}>{msg}</li>
          // ? : 안전탐색연산자 - null이면 무시, null이 아니면 넘어가기
        ))}
      </ul>

      <p>2. 서버로 값 전달 후 응답 받은 (POST)</p>
      <button onClick={getUserInfo}>POST 요청 보내기</button>
      <p>{userMsg}</p>
    </div>
  );
};

export default Exam7;
profile
인생은 변수

0개의 댓글