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
Этот подход работал для меня.