๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒณ React

[React] Spring์œผ๋กœ POST ๋ณด๋‚ด๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•_ then ๋ฐฉ์‹๊ณผ async ๋ฐฉ์‹

by ._.sori 2026. 1. 29.

 

 

ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋Š” ๋‚ด๋‚ด
then ๋ฐฉ์‹์œผ๋กœ Spring์— ์š”์ฒญ์„ ๋ณด๋ƒˆ๋‹ค.
๊ทธ๋Ÿฌ๋‹ค ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ
async ๋ฐฉ์‹์œผ๋กœ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ฒŒ๋๋‹ค.
๋‘๋ฐฉ๋ฒ•์˜ ์ฐจ์ด๊ฐ€ ๋ญ˜๊นŒ?

 

 

 

1. ์ƒํ™ฉ์„ค๋ช…

 

๊ณ ๊ฐ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋ ค ํ•œ๋‹ค. ๊ณ ๊ฐ ์ •๋ณด๋Š” body์— ๋„ฃ์–ด POST ๋ฐฉ์‹์œผ๋กœ Spring์— ๋ณด๋‚ด์งˆ ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Spring์€ React์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ด๋‹ค. ์ด๋•Œ ์กฐ๊ฑด์ด ์žˆ๋‹ค. ๊ณ ๊ฐ ์ •๋ณด์— ๋“ค์–ด๊ฐ€๋Š” ์ดˆ๋Œ€ ์ฝ”๋“œ ๋ฒˆํ˜ธ๊ฐ€ ์ค‘๋ณต๋˜์–ด์„  ์•ˆ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ์ดˆ๋Œ€ ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต์ผ ๊ฒฝ์šฐ Spring์—์„œ React๋กœ 409๋ฅผ ๋ณด๋‚ผ ๊ฒƒ์ด๋‹ค. React๋Š” 409๋ฅผ Spring์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ›์œผ๋ฉด "์ดˆ๋Œ€์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." ๋ฌธ๊ตฌ๊ฐ€ ์‚ฌ์šฉ์ž ํ™”๋ฉด์— alert ๋  ๊ฒƒ์ด๋‹ค.

 

  • POST ๋ฐฉ์‹์œผ๋กœ ๋ณด๋‚ธ๋‹ค.
  • ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 409์ธ ๊ฒฝ์šฐ, "์ดˆ๋Œ€์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." alert
  • ok๊ฐ€ ๋ชป์˜ค๋ฉด "์ €์žฅ์„ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."

 

 

 


 

 

 

 

2. then ๋ฐฉ์‹

const handleSubmit = () => {
    // ๋ฐฑ์—”๋“œ๋กœ POST ์š”์ฒญ
    fetch("/api/customers", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(form),
    })
    .then((response) => {
        // 409 ์ค‘๋ณต ์ฝ”๋“œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
        if (response.status === 409) {
            alert("์ดˆ๋Œ€์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.");
            // ๋‹ค์Œ then์œผ๋กœ ๊ฐ€์ง€ ์•Š๊ณ  catch๋กœ ๋„˜๊น€
            throw new Error("DUPLICATE_CODE"); 
        }

        // ๋‚˜๋จธ์ง€ ์‘๋‹ต ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
        if (!response.ok) {
            alert("์ €์žฅ ์‹คํŒจ");
            throw new Error("SAVE_FAILED");
        }

        // ๋‹ค์Œ then์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์คŒ
        return response.json(); 
    })

...
then ๋ฐฉ์‹์€ ๋น„๋™๊ธฐํ•จ์ˆ˜์ด๋‹ค. ๋งจ ์ฒ˜์Œ then์„ ๋ณด๊ณ  ๋ฌธ์ œ ์—†์œผ๋ฉด ๋‹ค์Œ then์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ, ์ฝ”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•  ๊ธฐ๋Šฅ์ด ์ ์„ ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋กœ์ง์ด ๋ณต์žกํ•ด์ง€๋ฉด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ฑฐ๋‚˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์ค‘๊ฐ„ ์ค‘๊ฐ„์— ํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ๋ฌผ๋ก  ๋‚จ์€ ์—๋Ÿฌ๋Š” .catch( )์—์„œ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 


 

 

3. async ๋ฐฉ์‹

   try {
            // ๋ฐฑ์—”๋“œ๋กœ POST ์š”์ฒญ
            const response = await fetch("/api/customers", {
                method: "POST",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify(form),
            });

            // 409 ์ค‘๋ณต ์ฝ”๋“œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
            if (response.status === 409) {
                alert("์ดˆ๋Œ€์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.");
                return;
            }

            // ๋‚˜๋จธ์ง€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
            if (!response.ok) {
                alert("์ €์žฅ ์‹คํŒจ");
                return;
            }

            const savedCustomer = await response.json();
            ...
            
            } catch (error) {
            console.error(error);
            alert("์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."); // ํ˜น์‹œ ๋ชจ๋ฅผ ๋‹ค๋ฅธ ์—๋Ÿฌ๋“ค ์—ฌ๊ธฐ์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•จ
        }
    };
async ๋ฐฉ์‹์€ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ์ ์ธ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ํ•ด์ค€๋‹ค. ์ด ๋ง์ด ์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ๋  ์ˆ˜ ์žˆ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด์„œ ์•ž์ฃผ์ž๊ฐ€ ํ•  ์ผ์„ ๋‹ค ๋๋‚ด์•ผ๋งŒ ๋‹ค์Œ ์ฃผ์ž๊ฐ€ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ (๋น„๋™๊ธฐ), async ๋ฐฉ์‹์„ ์ด์šฉํ•˜๋ฉด ์•ž์ฃผ์ž๊ฐ€ ํ•  ์ผ์„ ๋‹ค ๋๋‚ด์ง€ ๋ชปํ•ด๋„ ๋‹ค์Œ ์ฃผ์ž๊ฐ€ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ํ•ด์ค€๋‹ค(๋™๊ธฐ). 

์—ฌ๊ธฐ์„œ ์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋งˆ์น˜์ง€ ๋ชปํ•œ ์ผ์„ ์ž ๊น ์ผ์‹œ์ •์ง€ ํ•ด๋‘๊ณ  ๋‹ค๋ฅธ ์ผ์„ ํ•˜๊ณ  ๋‚œ ๋’ค, ๋งˆ์น˜์ง€ ๋ชปํ–ˆ๋˜ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด์ด ๋˜์—ˆ์„ ๋•Œ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์„œ ๋๋‚ด๋Š” ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

๋ณดํ†ต async ๋ฐฉ์‹์€ try-catch์™€ ํ•จ๊ป˜ ๋งŽ์ด ์“ด๋‹ค. ์™œ๋ƒ๋ฉด async๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐ›๋Š” ๊ตฌ๋ฌธ์ด ๋”ฐ๋กœ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ ‡๊ฒŒ try-catch ๊ตฌ๋ฌธ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ๋กœ์ง๊ณผ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์ง๊ด€์ ์ด๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด async ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.