๐Ÿ’ป TIL 2023.02.15

๊น€์˜์šฐ(Yeongwoo Kim)ยท2023๋…„ 2์›” 15์ผ
0
post-thumbnail

โœ… ๋ฌธ์ œ

  • Next Js๋กœ ๊ฐœ๋ฐœํ•˜๋˜ ์ค‘ mui๋ฅผ ์‚ฌ์šฉํ•˜์ž ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ
  • ์ฒ˜์Œ ๋ Œ๋”์‹œ์—๋งŒ ์˜ค๋ฅ˜๊ฐ€ ๋œจ๊ณ  ํ™”๋ฉด์— UI๊ฐ€ ๋‚˜ํƒ€๋‚œ ๋’ค์—๋Š” ๋ฌธ์ œ์—†์ด ์ž‘๋™ํ•จ

๐Ÿคท Hydration์ด๋ž€?

Hydration์€ ์ˆ˜๋ถ„ ๊ณต๊ธ‰์ด๋ผ๋Š” ๋œป์„ ๊ฐ€์ง„ ์˜์–ด ๋‹จ์–ด์ด๋‹ค. ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ ์–ธ์–ด์˜ Hydration์€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€ ์•Œ์•„๋ณด์ž.

  • Next Js๋Š” SSR(Server Side Rendering)๊ณผ CSR(Client Side Rendering)์„ ๋ณ‘ํ–‰ํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์—ฌ๊ธฐ์„œ SSR์˜ ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋‹จ์ ์œผ๋กœ๋Š” SSR์€ HTML์„ ๊ทธ๋ ค์ค„ ์ˆ˜๋Š” ์žˆ์–ด๋„ ์‹ค์ œ๋กœ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ Œ๋”๋ง ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— Javascript์˜ ์ฝ”๋“œ๋ฅผ DOMElement์™€ ๋งค์นญ์‹œ์ผœ์„œ ๋™์ ์ธ ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•˜์ง€๋Š” ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • SSR๋กœ ์ธํ•ด ๋ Œ๋”๋ง ๋œ HTML ํŽ˜์ด์ง€๋Š” ๋ผˆ๋Œ€๋งŒ ์กด์žฌํ•˜๋Š” ๋ฐ”์‹น ๋งˆ๋ฅธ ํ˜•ํƒœ๋กœ ์กด์žฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด๋•Œ ์ˆ˜๋ถ„ ๊ณต๊ธ‰์„ ํ•ด์ฃผ๋Š” ๊ฒƒ์„ Hydration์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
Hydrate๋Š” DOM tree์— ํ•ด๋‹น๋˜๋Š” DOM ์š”์†Œ๋ฅผ ์ฐพ์•„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์†์„ฑ(์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ๋“ฑ)๋“ค์„ ๋ถ€์ฐฉํ•˜๋Š” ์ผ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ 

  1. ์ดˆ๊ธฐ ๋กœ๋”ฉ์†๋„ ๊ฐ์†Œ

    • Pre-Renderingn๋œ Document๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์š”์†Œ๊ฐ€ ๋น ์ง„ ๊ฐ€๋ฒผ์šด ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋น ๋ฅด๊ฒŒ ๋กœ๋”ฉ์ด ๊ฐ€๋Šฅํ•œ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๊ฒ€์ƒ‰์—”์ง„ ์ตœ์ ํ™”

๐Ÿ” ์›์ธ ํŒŒ์•…

  • ssr์—์„œ ์ฒ˜์Œ์— ๋‚ด๋ ค์ฃผ๋Š” UI(pre-render)์™€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฒซ ๋ฒˆ์งธ๋กœ ๋ Œ๋”๋˜๋Š” UI ํŠธ๋ฆฌ๊ฐ„์— ์ฐจ์ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚œ ๋ฌธ์ œ๋‹ค.
  • ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋Š” React์˜ ํŠน์ง•์ธ Hydration์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.
  • ์ฆ‰, React ํŠธ๋ฆฌ๊ฐ€ DOM๊ณผ ๋™๊ธฐํ™”๋˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๋‹ค.

โ—๏ธ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ฝ”๋“œ

studyPage.tsx

<Box
          sx={{
            width: '100vw',
            borderBottom: '1px solid black',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <Tabs
            value={value}
            onChange={handleChange}
            textColor="primary"
            indicatorColor="none"
            sx={{
              '& button:active': { backgroundColor: 'black' },
              '& button.Mui-selected': {
                backgroundColor: 'black',
                color: '#dcfc73',
                border: '1px solid white',
              },
              width: '59.16vw',
            }}
          >
            <Tab
              value={0}
              label="๊ฐ•์˜ ๋ชฉ๋ก"
              sx={{
                width: '100%',
                maxWidth: '50%',
                borderLeft: '1px solid black',
              }}
            />
            <Tab
              value={1}
              label="์‹ค์‹œ๊ฐ„ ์ˆ˜์—…"
              sx={{
                width: '100%',
                maxWidth: '50%',
                borderRight: '1px solid black',
              }}
            />
          </Tabs>
        </Box>
        <Box sx={{ padding: 2, width: '59.16vw' }}>
          {value === 0 && (
            <Typography>
              <StudyList studyList={studyData.lecture} />
            </Typography>
          )}
          {value === 1 && <Typography>The second tab</Typography>}
        </Box>

StudyList.tsx

const StudyList = (studyList: StudyListType) => {
  const list = studyList.studyList;

  return (
    <>
      {Object.entries(list).map(([week, data]) => (
        <div key={week}>
          <div key={week}>{week}</div>
          {Object.entries(data).map(([lecture, info]) => (
            <div key={lecture}>
              <Accordion>
                <AccordionSummary
                  expandIcon={<ArrowDropDownIcon />}
                  aria-controls="panel1a-content"
                  id="panel1a-header"
                >
                  <Typography>
                    {lecture} {info.title}
                  </Typography>
                </AccordionSummary>
                <AccordionDetails>์œ ํŠœ๋ถ€ ์˜์ƒ</AccordionDetails>
              </Accordion>
            </div>
          ))}
        </div>
      ))}
    </>
  );
};
  1. MUI Box, Tabs, Tab์„ ํ†ตํ•ด studyList.tsx์— Tab๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๊ณ , ๋ฐ‘์— Box๋ฅผ ๋งŒ๋“ค์–ด Tab์„ ํด๋ฆญ ํ–ˆ์„๋•Œ ๋‚˜์™€์•ผํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค.
    	<Box sx={{ padding: 2, width: '59.16vw' }}>
          {value === 0 && (
            <Typography>
              <StudyList studyList={studyData.lecture} />
            </Typography>
          )}
          {value === 1 && <Typography>The second tab</Typography>}
        </Box>
  2. StudyList๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ณผ์ •์—์„œ Hydration error๊ฐ€ ๋ฐœ์ƒํ•จ์„ ์ฐพ์•„๋ƒˆ๊ณ , ์ฒ˜์Œ์—๋Š” StudyList ์ž์ฒด๊ฐ€ ์˜ค๋ฅ˜์ธ๊ฐ€ ์‹ถ์–ด์„œ StudyList ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ดค๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๊ณ , ํ•ด๋‹น ์ฝ”๋“œ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

๐Ÿ‘ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

  1. ์‚ฌ์‹ค ๋ฌธ์ œ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ–ˆ๋‹ค. MUI์˜ ์ฝ”๋“œ๋Œ€๋กœ tab์š”์†Œ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ์“ฐ๋ ค๊ณ  ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๊ฒฐ๊ณผ์˜€๋‹ค.
    <Typography>
          <StudyList studyList={studyData.lecture} />
    </Typography>
  2. ํ•ด๋‹น ๋ถ€๋ถ„์€ ์š”์†Œ์˜ ์ˆœ์„œ์— ๋งž์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํ•ด๋‹น ์ฝ”๋“œ๋Š” ๊ฒฐ๊ตญ <p>ํƒœ๊ทธ ์•ˆ์— <div> ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” ํ˜•ํƒœ์˜€๊ธฐ ๋•Œ๋ฌธ์ด์˜€๋‹ค.

๋Š๋‚€์ 

  • ์‚ฌ์‹ค ์ฒ˜์Œ์— ์˜ค๋ฅ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ๋œจ๊ณ , hydration์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์ „ํ˜€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋ ค์šด ๋ฌธ์ œ์ผ๊ฑฐ๋ผ๊ณ  ๊ฒ์„ ๋จน์–ด ์Šค์Šค๋กœ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์–ด๋ ต๊ฒŒ ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
  • ๋ฌธ์ œ์˜ ๋ฟŒ๋ฆฌ์ธ hydration์— ๋Œ€ํ•ด ์ •๋ฆฌ๋ฅผ ํ•˜๋‹ค๋ณด๋‹ˆ ui๋ฅผ ๊ทธ๋ฆฌ๋Š” ๊ณผ์ •์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ , ์ฝ”๋“œ๋ฅผ ๋ดค์„ ๋•Œ

    ํƒœ๊ทธ ์•ˆ์—

    ํƒœ๊ทธ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๊ณ  ์ฐธ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์˜€๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.
  • mui๋ฅผ ์“ฐ๋”๋ผ๋„ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ •ํ™•ํžˆ ํŒŒ์•…ํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“  ํ•˜๋ฃจ์˜€๋‹ค!

๐Ÿ“„ ์ฐธ์กฐ

https://www.univdev.page/posts/nextjs-hydration/
https://velog.io/@jhplus13/NextJS-React-Hydration-Error-%ED%95%B4%EA%B2%B0%EA%B8%B0

profile
์ฐจ๊ทผ์ฐจ๊ทผ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค

0๊ฐœ์˜ ๋Œ“๊ธ€