๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ํ”„๋กœ์ ํŠธ/๐Ÿ‘‘ VIP ์ดˆ๋Œ€์žฅ ๐Ÿ’Œ

[Spring, React] useEffect๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ ์ €์žฅ๋œ ๊ณ ๊ฐ์ •๋ณด๊ฐ€ ๋ณด์ด๋„๋ก ํŽ˜์ด์ง€์— ๋ฐ˜์˜ํ•ด๋ณด์ž

by ._.sori 2025. 12. 18.

 

 

๊ณ ๊ฐ ๋ช…๋‹จ ํ™”๋ฉด์„ ๋„์šฐ๋ฉด DB์— ์ €์žฅ๋œ ๋ช…๋‹จ์„ ๊ฐ€์ ธ์™€ ๋ณด์—ฌ์ค˜์•ผํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ํƒญ์— ๋“ค์–ด์˜ค๋ฉด
DB์— ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ์–ด๋„ ํ™”๋ฉด์— ๊ฐ€์ ธ์˜ค์ง€ ๋ชปํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ์ด ๋ถ€๋ถ„์„ ๊ฐœ์„ ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

 

 

 

 

1. ํ™˜๊ฒฝ์„ค์ •

  • ํ”„๋ก ํŠธ์—”๋“œ = React + Vite +WebStorm
  • ๋ฐฑ์—”๋“œ = Spring + IntelliJ
  • DB = MySQL + MySQLWorkbench

 

 


 

 

 

2. ๋ฌธ์ œ์ 

  • ํ™”๋ฉด
sori๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ €์žฅํ–ˆ๋‹ค. MySQLWorkbench๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์ œ๋Œ€๋กœ ์ €์žฅ๋˜์–ด์žˆ๋‹ค. ์ด์ œ ๋‹ค์‹œ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ–ˆ๋‹ค. ๋“ฑ๋ก๋๋˜ sori๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ MySQLWorkbench์—๋Š” ์ž˜ ์ €์žฅ๋˜์–ด์žˆ๋Š” ์ƒํƒœ์˜€๋‹ค. ์™œ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๊ฑธ๊นŒ?

 

 

  • ์›๋ž˜ ์ฝ”๋“œ
// ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ๊ณ ๊ฐ ๋ชฉ๋ก
const [rows, setRows] = useState([]);
useState๋Š” ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. React๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋‚˜์˜ค๋Š” ์ดˆ๊ธฐ ํ™”๋ฉด์—์„œ๋„ useState๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์•„๋ž˜ ๋งํฌ๋ฅผ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๋ฉด ์‰ฝ๊ฒŒ ๊ทธ ์˜ˆ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ถ”๊ฐ€ํ•œ ๊ณ ๊ฐ์˜ ์ •๋ณด๊ฐ€ ๋ฐ”๋กœ ํ™”๋ฉด์— ๋ฐ˜์˜๋˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด useState๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ •๋ณด๊ฐ€ ์•Œ์•„์„œ ์œ ์ง€๋  ์ค„ ์•Œ์•˜๋Š”๋ฐ, ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋‹ˆ ์‚ฌ๋ผ์กŒ๋‹ค.  ์™œ useState๋Š” ์ƒˆ๋กœ๊ณ ์นจ์‹œ ์‚ฌ๋ผ์ง€๋Š”๊ฑธ๊นŒ?

์ผ๋‹จ ๊ทธ ์ด์œ ๋ฅผ ๋งํ•˜๊ธฐ ์ „์—, useState์— ๋Œ€ํ•ด ์•Œ๋ฉด ๋” ์ข‹๋‹ค. useState๋Š” ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์œผ๋กœ ๋ง๊ทธ๋Œ€๋กœ ๋ฐฐ์—ด์˜ ๊ตฌ์กฐ๋ฅผ ๋ถ„ํ•ดํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ๋งํ•œ๋‹ค. [rows, setRows] ์ด๋Ÿฐ ํ˜•ํƒœ๋ฅผ ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ผ๊ณ  ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ useState๋Š” ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ [something, setSomething]๊ณผ ๊ฐ™์€ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค. ์ „์ฒด์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”์ง€๋ฅผ ์‚ดํŽด๋ณด์ž. const [ํ˜„์žฌ state(์ฒ˜์Œ์—” ์ดˆ๊ธฐ๊ฐ’์ด ๋“ค์–ด์˜ด), ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•  setํ•จ์ˆ˜] = useState(์ดˆ๊ธฐ๊ฐ’); ์ด๋ ‡๊ฒŒ ์ ๋Š”๋‹ค. 

useState ๊ฐ’์€ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋‹ค. ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ ๊ณ ๊ฐ ๋ชฉ๋ก์„ useState๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๊ฒŒ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ, ๋ฉ”๋ชจ๋ฆฌ ํŠน์ง•์ด ์ ์šฉ๋œ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ง•์€ ํƒญ์„ ๋‹ซ๊ฑฐ๋‚˜ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ์ดˆ๊ธฐ๊ฐ’์ธ useState([]);๊ฐ€ ๋˜์–ด ์•„๋ฌด๊ฒƒ๋„ ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ์ด์ œ ๋ฌธ์ œ๋ฅผ ์•Œ๊ฒŒ ๋๋‹ค. ๋ฌธ์ œ๋ฅผ ์•Œ๊ฒŒ๋˜๋‹ˆ๊นŒ ์ด๊ฒŒ ๋‹น์—ฐํ•˜๊ฒŒ ๋ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋Š”์ง€ ์˜๋ฌธ์ด๋‹ค! ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด ์–ธ์ œ๋‚˜ '์ด๋Ÿฐ ๊ฒƒ๋„ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š”๊ฑฐ์˜€๊ตฌ๋‚˜...'ํ•˜๊ณ  ์ƒ๊ฐํ•˜๊ฒŒ ๋œ๋‹ค. ์ด์ œ ๋ฌธ์ œ๋ฅผ ๊ณ ์ณ๋ณด์ž!

 

 

- usestate

 

useState – React

The library for web and native user interfaces

ko.react.dev

 

 

 

 


 

 

 

 

3. ์ฝ”๋“œ ์ˆ˜์ •

  • ์–ด๋–ป๊ฒŒ?
    ์ฒ˜์Œ์— ์ƒ๊ฐํ–ˆ์„๋• ๋Œ€๋Œ€์ ์ธ ๊ณต์‚ฌ๊ฐ€ ์ด๋ค„์งˆ ๊ฒƒ ๊ฐ™์•˜๋‹ค. ์ €์žฅ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ๋ถ€ํ„ฐ ๋‹ค ๋œฏ์–ด ๊ณ ์ณ์•ผํ•˜๋Š”์ค„ ์•Œ์•˜๋‹ค.(์ €์žฅ์„ ๋ˆ„๋ฅด๋ฉด useEffect๋กœ DB์— ์ €์žฅ๋œ ์ •๋ณด๋ฅผ ๋“ค๊ณ ์™€์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค) ๊ทธ๋Ÿฐ๋ฐ ๊ณฐ๊ณฐํžˆ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๊ทธ๋ƒฅ ํ™”๋ฉด์ด ์ฒ˜์Œ ๋ณด์—ฌ์งˆ๋•Œ๋งŒ useEffect๋กœ DB์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜๋ฉด useState๋กœ ์—…๋ฐ์ดํŠธ๋œ ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ ํƒญ์„ ์—ด๋ฉด ๊ทธ๋• useEffect๊ฐ€ DB์—์„œ ์ •๋ณด๋ฅผ ๊บผ๋‚ด์™€ ๋ณด์—ฌ์ค„ํ…Œ๋‹ˆ, ๋ฌธ์ œ ์—†๊ฒŒ ๋œ๋‹ค. 


  • React - useEffect ์ฝ”๋“œ
    useEffect(() => {
        const effectCustomers = () => {
            // ๊ฒฝ๋กœ๋กœ ๋ณด๋‚ด์ž(GET๋ฐฉ์‹) -> spring์˜ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌ
            fetch("/api/customers")
                // ์‘๋‹ต์„ ๋ฐ›๊ณ  ๋ฐ”๋””๋ฅผ json์„ ํŒŒ์‹ฑํ•ด์„œ JS๊ฐ์ฒด๋กœ ๋ณ€๊ฒฝ
                .then((response) => {
                    return response.json();
                })
                // data์— ๋‹ด์€ ๋’ค, useState ์ฝ”๋“œ์— ์žˆ๋Š” setRows์— ๋ณด๋‚ด ํ™”๋ฉด ์—…๋ฐ์ดํŠธ
                .then((data) => {
                    setRows(data);
                })
                // ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์ฒ˜๋ฆฌํ•˜๊ธฐ
                .catch((error) => {
                    console.error(error);
                    alert("๊ณ ๊ฐ ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.");
                });
        };

        // effectCustomers ์‹คํ–‰
        effectCustomers();
    }, []);
useEffect๋Š” ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋Š” React Hook์ด๋‹ค. ์—ฌ๊ธฐ์„œ React Hook์€ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌํ•จ ๊ฐ™์€ ์กด์žฌ์ธ๋ฐ useEffect ๋ง๊ณ ๋„ useState๋„ Hook ์ค‘ ํ•˜๋‚˜์ด๋‹ค. React Hook์— ๋Œ€ํ•œ ๋งํฌ๋ฅผ ์•„๋ž˜์— ๋‹ฌ์•„๋‘๊ฒ ๋‹ค.

React๋Š” ์›๋ž˜ UI๋ฅผ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‹ค๋ณด๋ฉด ๊ทธ๋ฆฌ๋Š” ๊ฒƒ ์™ธ์— ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค. ์ง€๊ธˆ ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์ฒ˜๋Ÿผ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๊ฑฐ๋‚˜, ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ์•Œ๋ฆผ ํ˜น์€ ํƒ€์ด๋จธ๊ฐ™์€ ๊ธฐ๋Šฅ๋„ useEffect๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. 

 

// ๊ฐ™์€ ์ฝ”๋“œ ๋” ๊น”๋”ํ•œ ๋ฒ„์ „ - GPT

useEffect(() => {
    
    // useEffect ์•ˆ์—์„œ๋Š” ์ง์ ‘ async๋ฅผ ์“ธ ์ˆ˜ ์—†๋‹ค.
    // ๋‚ด๋ถ€์— async ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ํ˜ธ์ถœํ•˜๋Š” ํŒจํ„ด์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
    // ๋ณดํ†ต์€ async ํ•จ์ˆ˜๊ฐ€ ์™ธ๋ถ€์— ์žˆ๋‹ค.
    const effectCustomers = async () => {
        try {
            // GET ์š”์ฒญ
            const response = await fetch("/api/customers");
            // ์‘๋‹ต ๋ฐ”๋””๋ฅผ JS ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
            const data = await response.json();
            // useState์˜ setRows์— data๋ฅผ ๋„ฃ์–ด ํ™”๋ฉด ์—…๋ฐ์ดํŠธ 
            setRows(data);
        } catch (error) {
            console.error(error);
            alert("๊ณ ๊ฐ ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.");
        }
    };

    // effectCustomers ์‹คํ–‰
    effectCustomers();

}, []);

 

 

 

- hooks

 

๋‚ด์žฅ React Hook – React

The library for web and native user interfaces

ko.react.dev

 

 

- useEffect์™€ sideEffect์˜ ์ฐจ์ด์ 

 

[React] useEffect์™€ sideEffect

useEffect๋ž€? React์—์„œ ์ œ๊ณตํ•˜๋Š” useEffect()๋Š” sideEffect๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋ฆฌ์•กํŠธ์˜ ์ˆœ์ˆ˜ํ•œ ํ•จ์ˆ˜์ ์ธ ์„ธ๊ณ„์—์„œ ๋ช…๋ น์ ์ธ ์„ธ๊ณ„๋กœ์˜ ํƒˆ์ถœ๊ตฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์ฆ‰, ๋ Œ๋”๋ง ์ด์™ธ์— ์ผ์œผ

voyage-dev.tistory.com

 

 

- ์ฝ”๋“œ์ฐธ๊ณ 

 

[React] SpringBoot ์™€ React ์—ฐ๋™ํ•˜๊ธฐ - vite build

Thymeleaf์™€ ๊ฐ™์€ ํ…œํ”Œ๋ฆฟ ์—”์ง„ ๊ธฐ๋Šฅ ์—†์ด SpringBoot๋ฅผ API ์„œ๋ฒ„๋กœ๋งŒ ํ™œ์šฉํ•˜๊ณ  React์™€ ๊ฐ™์€ ๋ณ„๋„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ†ตํ•ด UI๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐฑ์—”๋“œ์™€ ํ”„๋ŸฐํŠธ์—”๋“œ ๊ธฐ์ˆ ์Šคํƒ์„ ๊ฐ๊ฐ SpringBoot์™€ React๋กœ ๊ฒฐ

margin1103.tistory.com

 

 

  • Spring - Controller
    @GetMapping
    public List<Customer> effectCustomers() {
        return customerRepository.findAll();
    }
GET ๋ฐฉ์‹์œผ๋กœ ํ”„๋ก ํŠธ์—์„œ ์š”์ฒญ์„ ๋ณด๋ƒˆ์œผ๋‹ˆ, ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋„ GET ๋ฐฉ์‹์œผ๋กœ ๋ฐ›๋Š”๋‹ค.  ๊ทธ๋ฆฌ๊ณ  ๋ฐ˜ํ™˜ ํƒ€์ž…์€ List<Customer>๋กœ ํ–ˆ๋‹ค.  ์™œ๋ƒํ•˜๋ฉด ์ด ๋ฉ”์„œ๋“œ๋Š” ์—ฌ๋Ÿฌ ๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. Customer๋Š” ์—”ํ‹ฐํ‹ฐ์œผ๋กœ ์„ค์ •ํ–ˆ์œผ๋ฉฐ ์—”ํ‹ฐํ‹ฐ๋ž€, ํ…Œ์ด๋ธ”์„ ๊ด€๋ฆฌํ•  ๋•Œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ์˜ ์ง‘ํ•ฉ์ด๋‹ค. Customer์—๋Š” name, grade, phone, code, note๊ฐ€ ์žˆ๋‹ค.(์ด๊ฑธ ๊บผ๋‚ด์˜ค๋Š” ๊ฒƒ!) ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ ์ •๋ณด๋ฅผ ๊บผ๋‚ด๋Š”๋ฐ ์ด๋•Œ findAll๋กœ ๋ชจ๋“  ๊ณ ๊ฐ์„ ์กฐํšŒํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

  • ์ˆ˜์ • ํ›„ ํ™”๋ฉด