React에 통합하기

React 컴포넌트를 사용자 정의 컴포넌트로 사용하는 방법을 찾고 있다면 여기를 참고하세요.

React 프로젝트에 Univer를 통합하기 전에 Univer 설치 및 기본 사용법을 읽고 React의 기본 개념과 생명주기 훅을 이해했는지 확인하세요.

React 18 및 19와 Web SDK 통합하기

통합 단계

  1. useEffect 훅에서 Univer를 초기화합니다.
  2. useEffect 훅의 반환 함수에서 Univer를 제거합니다.

예제

마운트마다 별도의 자식 컨테이너를 사용합니다. 바깥 React 정리가 끝난 뒤 마이크로태스크에서 인스턴스를 폐기하여 React 커밋 중 중첩 루트의 동기 언마운트를 방지합니다.

TSX
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'import UniverPresetDocsCoreEnUS from '@univerjs/preset-docs-core/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import { useEffect, useRef } from 'react'import '@univerjs/preset-docs-core/lib/index.css'export function App() {  const containerRef = useRef<HTMLDivElement>(null)  useEffect(() => {    const host = containerRef.current    if (!host) return    const container = document.createElement('div')    container.style.height = '100%'    host.append(container)    const { univer, univerAPI } = createUniver({      locale: LocaleType.EN_US,      locales: {        [LocaleType.EN_US]: mergeLocales(          UniverPresetDocsCoreEnUS,        ),      },      presets: [        UniverDocsCorePreset({          container,        }),      ],    })    univerAPI.createDocument({})    return () => {      queueMicrotask(() => {        univer.dispose()        container.remove()      })    }  }, [])  return (    <div ref={containerRef} style={{ height: 600 }} />  )}

React 16.9+ 및 17과 Web SDK 통합하기

통합 전 참고 사항

호환성 참고 사항

Univer의 뷰 계층은 React 18.3.1을 기반으로 개발되었지만 React 16.9+ 및 17 프로젝트에도 최소한의 호환성 지원을 제공합니다. 낮은 React 버전을 계속 지원한다는 의미는 아닙니다. 최상의 사용 경험과 새로운 기능을 위해 가능한 한 빨리 최신 버전으로 업그레이드하는 것을 권장합니다.

빌드 도구 별칭 설정

React 16.9+ 및 17 환경에서는 빌드 도구의 별칭 기능을 사용하여 react-dom/client의 내보내기를 모의해야 합니다. 그렇지 않으면 일부 기능이 올바르게 작동하지 않을 수 있습니다.

Vite 설정 예제

TypeScript
export default defineConfig({  plugins: [react()],  resolve: {    alias: {      'react-dom/client': path.resolve(__dirname, './src/client.ts'),     },  },})
TypeScript
import ReactDOM from 'react-dom'export function createRoot(container: HTMLElement) {  return {    render: (element: JSX.Element) => {      ReactDOM.render(element, container)    },  }}

CDN/UMD 환경 대응

<script> 태그로 Univer와 React를 포함한다면 React를 가져온 뒤 다음 코드를 추가하여 react-dom/client의 내보내기를 모의해야 합니다.

HTML
<script>  /**   * With the support for React 19[^1], UMD users may need additional adaptation.   *   * [^1]: [support for React 19] https://github.com/dream-num/univer/pull/4247   */  /**   * Fix `Uncaught TypeError: client.createRoot is not a function`   * If using UMD React < 18, you might need the following code.   */  ;(function (global) {    'use strict'    if (!global.ReactDOM) {      throw new Error('ReactDOM must be loaded before ReactCreateRoot.')    }    const ReactDOM = global.ReactDOM    if (!ReactDOM.createRoot) {      ReactDOM.createRoot = function (container) {        return {          render: (element) => {            ReactDOM.render(element, container)          },        }      }    }  })(this)  /**   * Fix `Uncaught TypeError: jsxRuntime.jsx is not a function`   * If using UMD React, you might need the following code.   * Reference: https://unpkg.com/react@18.3.1/cjs/react-jsx-runtime.production.min.js   */  ;(function (global) {    'use strict'    if (!global.React) {      throw new Error('React must be loaded before ReactJSXRuntime.')    }    const React = global.React    if (!React.jsx || !React.jsxs) {      const REACT_ELEMENT_TYPE = Symbol.for('react.element')      const hasOwnProperty = Object.prototype.hasOwnProperty      const RESERVED_PROPS = {        key: true,        ref: true,        __self: true,        __source: true,      }      const ReactCurrentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner      function createReactElement(type, config, maybeKey) {        const props = {}        let key = null        let ref = null        if (maybeKey !== undefined) {          key = `${maybeKey}`        }        if (config.key !== undefined) {          key = `${config.key}`        }        if (config.ref !== undefined) {          ref = config.ref        }        for (var propName in config) {          if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {            props[propName] = config[propName]          }        }        if (type && type.defaultProps) {          const defaultProps = type.defaultProps          for (var propName in defaultProps) {            if (props[propName] === undefined) {              props[propName] = defaultProps[propName]            }          }        }        return {          $$typeof: REACT_ELEMENT_TYPE,          type,          key,          ref,          props,          _owner: ReactCurrentOwner.current,        }      }      React.jsx = createReactElement      React.jsxs = createReactElement    }  })(this)</script>

통합 단계

  1. useEffect 훅에서 Univer를 초기화합니다.
  2. useEffect 훅의 반환 함수에서 Univer를 제거합니다.

예제

TSX
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'import UniverPresetDocsCoreEnUS from '@univerjs/preset-docs-core/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import { useEffect, useRef } from 'react'import '@univerjs/preset-docs-core/lib/index.css'export function App() {  const containerRef = useRef<HTMLDivElement>(null)  useEffect(() => {    const host = containerRef.current    if (!host) return    const container = document.createElement('div')    container.style.height = '100%'    host.append(container)    const { univer, univerAPI } = createUniver({      locale: LocaleType.EN_US,      locales: {        [LocaleType.EN_US]: mergeLocales(          UniverPresetDocsCoreEnUS,        ),      },      presets: [        UniverDocsCorePreset({          container,        }),      ],    })    univerAPI.createDocument({})    return () => {      queueMicrotask(() => {        univer.dispose()        container.remove()      })    }  }, [])  return (    <div ref={containerRef} style={{ height: 600 }} />  )}

이 가이드는 어떠셨나요?

© 2026 DreamNum Co., Ltd.