개발자

Next.js의 dynamic import를 이용한 Ref 전달

2023년 11월 20일조회 478

현재 next.js 13버전과 toast ui calendar를 사용해서 프로젝트를 진행하고있습니다. toast ui calendar는 서버사이드에서는 렌더링이 되지 않기 때문에 dynamic 함수를 사용해서 import를 했습니다. dynamic 함수를 사용해서 import한 component에 ref를 넘기는 방법이 궁금합니다! https://careerly.co.kr/qnas/2078 위의 질문글을 보고 현재 아래 코드와 같이 작성을했는데 이렇게 작성을 하게된다면 결국 TuiCalendar라는 컴포넌트에는 ref={ref}, forwardRef를 사용해서 넘기는것이 아닌 forwardedRef라는 props로 ref를 넘기는형태가 되는건데 dynamic 함수를 사용해서 받아온 컴포넌트에 ref를 넘기는것은 이방법밖에 없을까요? 또한 "use client" import { useRef } from "react"; import Child from "./child"; export default function Parent (props : any) { const testRef = useRef(3) return ( <> <button onClick={() => console.log(testRef.current)}>버튼</button> <Child testRef={testRef} /> </> ) } 이것과 같이 ref를 그냥 props로 넘기는것과 ref + forwardRef 로넘기는 것의 차이점을 알고싶습니다!

1"use client";
2
3import dynamic from "next/dynamic";
4import React, { MutableRefObject } from "react";
5import { forwardRef, useRef } from "react";
6import styled from "styled-components";
7import useRequestCalendar from "../../hooks/useRequestCalendar";
8
9type CalendarInfo = {
10    id : string;
11    name : string;
12    backgroundColor? : string;
13    borderColor? : string;
14}
15
16type CalendarEvent = {
17    id : string;
18    calendarId : string;
19    title : string;
20    category : string;
21    start : string | Date;
22    end : string | Date;
23}
24
25interface IRequestMonthCalendar {
26    viewType? : "month" | "day",
27    calendars : CalendarInfo[],
28    events : CalendarEvent[],
29    ref? : MutableRefObject<any>
30}
31
32const TuiCalendar = dynamic(() => import("./tui_calendar"), { ssr: false });
33
34const ForwardedTuiCalendar = React.forwardRef(function ForwardedBizmateCalendar (props: IRequestMonthCalendar, ref: React.ForwardedRef<unknown>) {
35    return <TuiCalendar {...props} forwardedRef={ref} />
36});
37
38export default function RequestCalendar () {
39
40    const { events, date } = useRequestCalendar({
41        other_user_uid : "",
42        year : 2023,
43        month : 11
44    })
45    
46    const monthCalendarRef = useRef<any>(null);
47
48    return (
49        <Wrapper>
50            <button onClick={() => {
51                console.log('monthCalendarRef : ', monthCalendarRef.current);
52                // monthCalendarRef.current?.next()
53            }}>+</button>
54            <ForwardedTuiCalendar
55                calendars={[{
56                    id : "",
57                    name : "테스트이름",
58                    backgroundColor : '#dcedc8',
59                    borderColor : '#dcedc8'
60                }]}
61                events={events}
62                ref={monthCalendarRef}
63            />
64        </Wrapper>
65    )
66}
67
68
69
70const Wrapper = styled.div`
71    width: 100%;
72
73`
74
75/////////////////////////////////////////////
76// 아래는 TuiCalendar 코드입니다.
77
78"use client";
79
80import Calendar from "@toast-ui/react-calendar";
81import { MutableRefObject } from "react";
82
83type CalendarInfo = {
84    id : string;
85    name : string;
86    backgroundColor? : string;
87    borderColor? : string;
88}
89
90type CalendarEvent = {
91    id : string;
92    calendarId : string;
93    title : string;
94    category : string;
95    start : string | Date;
96    end : string | Date;
97}
98
99interface IRequestMonthCalendar {
100    viewType? : "month" | "day",
101    calendars : CalendarInfo[],
102    events : CalendarEvent[],
103    ref? : MutableRefObject<any>,
104    forwardedRef? : any,
105}
106
107export default function TuiCalendar (props : IRequestMonthCalendar, ref : any) {
108
109    console.log('ref : ', ref);
110
111    const { viewType = "month", calendars, events, forwardedRef } = props;
112
113    console.log('forwardedRef ', forwardedRef);
114
115    return (
116        <Calendar
117            height="600px"
118            // ref={ref} 
119            view={viewType}
120            calendars={calendars}
121            events={events}
122            gridSelection={{
123                enableClick : true,
124                enableDblClick: false
125            }}
126            useFormPopup={true}
127            useDetailPopup={true}
128            week={{
129                taskView : false
130            }}
131            eventFilter={(event) => true}
132        />
133    )
134}
이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 0

답변이 없을 때 보이는 아이콘

첫 답변을 기다리고 있어요.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2023년 11월 20일

Next.js의 dynamic import 기능을 이용해서 서버사이드 렌더링이 되지 않는 컴포넌트를 사용할 수 있습니다. dynamic import된 컴포넌트에 ref를 전달하는 방법으로는 forwardRef를 이용하는 것이 대표적입니다. forwardRef는 컴포넌트에 ref 속성을 명시적으로 전달해주기 위해 사용합니다. 일반적인 React 컴포넌트는 props로 받은 ref를 자식 컴포넌트에게 직접 전달할 수 없기 때문에 React에서 제공하는 특별한 API인 forwardRef를 이용합니다. 위 코드에서 TuiCalendar 컴포넌트에 forwardedRef라는 이름으로 ref를 넘겨주고 있으나, 실제로 Calendar 컴포넌트가 사용할 수 있도록 `ref={forwardedRef}` 형태로 수정해야 합니다. 그리고 Ref를 prop로 넘기는 것과 forwardRef로 넘기는 것의 차이점은 다음과 같습니다. - Ref를 그냥 prop으로 넘기면, 조상 -> 부모 -> 자식 순서로 직접 연결되어야 하며, 중간의 모든 컴포넌트들이 ref와 관련된 로직을 알고 처리해 줘야 한다는 단점이 있습니다. - 반면, forwardRef를 사용하면 이러한 단점을 해소하고 조상 컴포넌트가 자식 컴포넌트에 ref를 바로 연결할 수 있습니다. 이를 통해 중간에 있는 부모 컴포넌트는 ref와 관련된 로직을 몰라도 됩니다. 따라서, 복잡한 계층 구조에서 deep down에 위치한 자식 컴포넌트에 ref를 전달해야 하는 경우 forwardRef 사용이 좋습니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!