리액트가 아니지만 같은 어플리케이션 내에 존재하는 곳에서 특정 리액트 컴포넌트의 상태를 변경하고 싶다면 어떻게 할까요?
해봅시다
간단한 카운터가 있습니다. 카운트 상태를 가지고 클릭하면 카운트가 증가하는 형태입니다.
import { useState } from "react";
export let outsider = () => {};
export default function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount((prev) => prev + 1);
};
outsider = () => {
setCount((prev) => prev + 1);
};
return (
<div>
<button onClick={handleClick}> 리액트 안에서</button>
<div>{count}</div>
</div>
);
}
중간에 outsider
라는 함수가 보입니다. 외부에서 호출하기 위해서 선언은 컴포넌트 바깥에서 해줍니다.
outsider
가 호출되면 위 컴포넌트의 카운트가 증가시키는 형태인데요. 진짜 증가할까요? 해봅시다.
index.html에서 버튼 태그를 생성해줍니다.
<button id="outsider-button">리액트 바깥에서</button>
생성된 버튼 태그를 찾아서 카운터 컴포넌트에서 불러온 outsider
함수를 이벤트로 등록해줍시다.
import { outsider } from "./Counter";
export default function Outsider() {
const outsiderButton = document.getElementById("outsider-button");
if (outsiderButton)
outsiderButton.addEventListener("click", () => outsider());
return;
}
그리고 마지막으로 위 Outsider
함수를 어플리케이션이 시작하는 지점에서 호출해줍시다.
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import Outsider from "./Outsider";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement!);
root.render(
<StrictMode>
<App />
</StrictMode>
);
Outsider();
왜 작동하는 걸까요?
ES 모듈에서는 모듈 내의 값을 다른 모듈에서 사용하게 되면 내보낸 쪽의 모듈 내의 값이 변경하는 특징을 가지고 있습니다. 이러한 형태를 라이브 바인딩이라고 합니다.
이 라이브 바인딩을 이용하여서 리액트 외부에서 리액트의 상태를 변경 할 수 있습니다.
마무리
자주 사용될 패턴은 아니지만, 알아두면 한번쯤 쓰지 않을까요?
참고
https://simbathesailor.dev/how-to-trigger-react-components-from-outside-react/ https://stackoverflow.com/questions/52211309/what-does-it-mean-by-live-bindings