简体   繁体   中英

Next.js: How to dynamically import external client-side only React components into Server-Side-Rendering apps developed?

I know this question has been asked multiple times before but none of the solution seems to work.

I'm trying to use the library 'react-chat-popup' which only renders on client side in a SSR app.(built using next.js framework) The normal way to use this library is to call import {Chat} from 'react-chat-popup' and then render it directly as <Chat/> .

The solution I have found for SSR apps is to check if typedef of window !=== 'undefined' in the componentDidMount method before dynamically importing the library as importing the library normally alone would already cause the window is not defined error. So I found the link https://github.com/zeit/next.js/issues/2940 which suggested the following:

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

However, my foo object becomes null when I do this. When I print out the m object in the callback, i get {"__webpackChunkName":"react_chat_popup_6445a148970fe64a2d707d15c41abb03"} How do I properly import the library and start using the <Chat/> element in this case?

I've managed to resolve this by first declaring a variable at the top:

let Chat = ''

then doing the import this way in componentDidMount:

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

and finally render it like this:

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

Next js now has its own way of doing dynamic imports with no SSR.

import dynamic from 'next/dynamic'

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

Here is the link of their docs: next js

You mentioned the solution yourself, this component should only run clientside, hence you can only render it on the client using a condition. Doing the following will only render the component on the client and solve your issues:

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

You don't have to worry about how to import the component, just import {Chat} from 'react-chat-popup' it as any other component and it will be added to the clientside bundle (as well as the server side but it's server, so it's fine to have it there even though it's not used).

This might be worth a read: https://github.com/zeit/next.js/issues/2473

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM