그러면 어떻게 참조의 도움을 이 대화창을
TimerChallenge에서 접근할 수 있을까요?
그건, 여기에 ref (참조)를 생성함으로 시작해보겠습니다
이 TimerChallenge 컴포넌트 안에 말입니다
이름 dialog (대화창)으로 짓겠습니다
이름은 물론 여러분 자유입니다
이제 다음 단계들을 진행할 수 있습니다
ResultModal (결과창)에 가서
ref라는 이름의 prop (속성)을 추가해줍니다
우리의 컴포넌트이기 때문에
이름은 마음대로 지으셔도 됩니다
그리고 이 dialog 참조의 값을
이 ResultModal 컴포넌트의 ref 속성으로 전달합니다
그 컴포넌트에서는 이제 구조 분해 할당을 하고
여기에 지정해보겠습니다
이 특별한 참조 속성의 값으로 쓰는 것입니다
모든 내장 컴포넌트에서 사용 가능한 기능입니다
그리고 결국엔 그 참조를
즉, 여기 TimerChallenge에 정의된 참조를
ResultModal의 dialog 요소로 전달하는 것입니다
그래서 이제 우리는
타이머가 만료되었을 때
이 dialog 참조를 사용해서 current에 접근할 수 있습니다
그 다음엔 이 dialog 요소를 값으로 보관하고
showModal을 호출할 것입니다
왜냐하면 내장 dialog 요소는
showModal 메소드를 가지고 있으며
호출하여 표시할 수 있습니다
전에 언급했듯이
별도의 설정 없이는 보이지 않게 되어 있지만
하지만 이 showModal 메소드를 호출하면 보이도록 바뀝니다
이건 리액트와는 연관이 없는 문제고
표준 브라우저 기능 중 하나입니다
이제 확실히 해야하는 것은
이 ResultModal이 항상 렌더링되어야 한다는 것입니다
왜냐하면 이건 보이지 않고
애초에 보이는 DOM의 일부가 아니기 때문에
이런 식으로 사용하는 것은 문제를 일으키지 않습니다
저장하고 앱을 재로딩해보면
대화창이 보이지 않습니다
그러므로 이런 식으로 매번 주변에 두는 건 문제가 되지 않습니다
하지만 이제 시작한 다음 이 타이머가 만료될 때까지 내버려 두면
아무 일도 일어나지 않습니다
대신, 여기 에러가 생겼습니다
ref (참조)는 prop (속성)이 아니라고 뜨네요
그러니까 결국은
이 메시지가 조금 아리송하긴 하지만
문제는 우리가 참조를
다른 컴포넌트로 전달할 수 없다는 것입니다
그리고 그 컴포넌트의 요소에도 물론 전달할 수 없습니다
그리고 그걸 여기에서 시도한 것입니다
안타깝게도 이렇게는 작동하지 않습니다
대신, 만약에 참조를
컴포넌트에서 다른 컴포넌트로 전달하고
그걸 그 컴포넌트에서 사용하고 싶다면
리액트가 제공하는 특별한 함수를 사용해야 합니다
리액트에서 무언가 import해야 하며
그 무언가는 바로 forwardRef (참조전달) 이라는 함수입니다
그리고 이 함수는 이름 그대로 할 일을 합니다
참조를 컴포넌트에서 컴포넌트로 전달하여
참조가 그 다른 컴포넌트에서 사용될 수 있도록 합니다
이 forwardRef 함수를 사용하려면
컴포넌트 함수를 감싸야 합니다
이런 식으로 말입니다
그러므로 여길 재구조 작업을 해야 하고
forwardRef를 호출한 값을
이렇게 상수에 저장합니다
그리고 default export로 상수를 내보냅니다
코드를 이런 식으로 구조를 다시 조정해서
forwardRef가 이 함수를 감싸도록 합니다
그것이 반환하는 값도 포함입니다
그것 또한 컴포넌트일 것이지만
리액트가 제어하는 컴포넌트는 아니고
상수에 저장되어 있으며 이것도 export됩니다
또한, 이런 식으로
참조 속성을 받고 구조 분해 할당해서는 안 됩니다
대신, 컴포넌트 함수를
forwardRef로 감쌀 때는
그 컴포넌트 함수는 두번째 인자를 받을 것입니다
이 속성 인자 다음에 말입니다
꼭 기억하셔야 할 게, 이 첫 번째 매개변수는
이 속성 매개변수이며 여기서 구조 분해 할당합니다
하지만 이제 이 컴포넌트 함수는
두 번째 매개변수, 즉 ref 매개변수를 받을 것입니다
그 이유는
우리가 이 컴포넌트 함수를 forwardRef로 감쌌기 때문입니다
그리고 이 ref는
우리 컴포넌트의 ref 속성의 도움으로 설정한 ref가 아닙니다
이 속성 또한 ref로 이름을 지어야
리액트가 인식할 수 있습니다
하지만 이제 ref가 있는데
dialog와 같은 값으로 사용될 수 있습니다
이 연결은
즉 timerChallenge 컴포넌트의 ref와
ResultModal 컴포넌트의 dialog 사이의 연결은
컴포넌트 경계선을 너머 수립되고 있는 것입니다
그러므로 이제 dialog.current.showModal를 호출하는 게
가능해야 합니다
그럼 저장하고 재로딩해봅시다
그리고 이걸 시작한 다음 타이머가 만료되게 두면
이제 이 모달 창이 뜨고
이 배경도 보입니다
제가 이전에 내장 기능이라고 말씀드렸었습니다
이제 표시되는 이유는 이제 이 모달을
showModal 메소드를 사용하여 띄우는 것이기 때문입니다
그리고 그걸 참조의 도움으로 사용할 수 있는 것이고
forwardRef의 역할이 컸습니다
그로 인해 참조를 전달할 수 있습니다
컴포넌트에서 컴포넌트로 전달할 수 있으니
TimerChallenge 컴포넌트에서
ResultModal 컴포넌트로도 전달이 가능합니다