Next.js: Как динамически импортировать только компоненты React на стороне клиента в разработанные приложения для рендеринга на стороне сервера?

Я знаю, что этот вопрос задавался несколько раз, но ни одно из решений, похоже, не работает.

Я пытаюсь использовать библиотеку "response-chat-popup", которая рендерится только на стороне клиента в приложении SSR (построено с использованием фреймворка next.js). Обычный способ использования этой библиотеки - это вызов import {Chat} from 'react-chat-popup' а затем сделать это прямо как <Chat/>,

Решение, которое я нашел для приложений SSR, состоит в том, чтобы проверить, typedef of window !=== 'undefined' в componentDidMount метод перед динамическим импортом библиотеки, так как обычно импорт библиотеки уже вызвал бы window is not defined ошибка. Поэтому я нашел ссылку https://github.com/zeit/next.js/issues/2940 которой предлагалось следующее:

Chat = dynamic(import('react-chat-popup').then(m => {
  const {Foo} = m;
  Foo.__webpackChunkName = m.__webpackChunkName;
  return Foo;
}));

Тем не менее, мой объект foo становится нулевым, когда я делаю это. Когда я распечатываю объект м в обратном вызове, я получаю {"__webpackChunkName":"react_chat_popup_6445a148970fe64a2d707d15c41abb03"} Как правильно импортировать библиотеку и начать использовать <Chat/> элемент в этом случае?

4 ответа

В Next js теперь есть собственный способ динамического импорта без SSR.

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  { ssr: false }
)

Вот ссылка на их документы: nextjs

Мне удалось решить эту проблему, сначала объявив переменную сверху:

let Chat = ''

затем выполнить импорт таким образом в componentDidMount:

async componentDidMount(){
        let result = await import('react-chat-popup')
        Chat = result.Chat
        this.setState({
            appIsMounted: true
        })
    }

и, наконец, сделать это так:

<NoSSR>
   {this.state.appIsMounted? <Chat/> : null}
</NoSSR>

Вы упомянули решение самостоятельно, этот компонент должен запускаться только на стороне клиента, поэтому вы можете отображать его только на клиенте, используя условие. Выполнение следующих действий приведет только к отрисовке компонента на клиенте и решению ваших проблем:

if (process.browser) {
  // client-side-only code
  <Chat/>
}

Вам не нужно беспокоиться о том, как импортировать компонент, просто import {Chat} from 'react-chat-popup' это как любой другой компонент, и он будет добавлен в клиентский пакет (так же как и на стороне сервера, но это сервер, так что хорошо иметь его там, даже если он не используется).

Это может быть стоит прочитать: https://github.com/zeit/next.js/issues/2473

Вы не всегда можете захотеть включать модуль на стороне сервера. Например, когда модуль включает библиотеку, которая работает только в браузере.

Обычно импортируйте библиотеку в дочерний компонент и динамически импортируйте этот компонент в родительский компонент.

https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

Этот подход работал для меня.

Другие вопросы по тегам