React 16: Warning: Expected server HTML to contain a matching
in <body>

前端 未结 8 2254
太阳男子
太阳男子 2020-12-17 08:37

Since upgrading to React 16 I get this error message:

warning.js:33 Warning: Expected server HTML to contain a matching

in .

相关标签:
8条回答
  • 2020-12-17 09:05

    If you're using Server Side Rendering like NextJS, delete recent code and compare if you've tried to access a variable directly inside of Component scope where DOM is not guaranteed yet. For me, it was:

    import { i18n } from 'i18n'
    
    export default function SomeComponent() {
        const initLanguage = i18n.language              <---- causing error
    
        return ...
    }
    

    If you need to access such properties, access it within useEffect, so as to make sure that document is already established by then. It is kinda equivalent to componentDidMount():

    import { i18n } from 'i18n'
    import { useEffect, useState } from 'react'
    
    export default function SomeComponent() {
        const [initlanguage, setInitLanguage] = useState('en')
    
        useEffect(() => setInitLanguage(i18n.language), [])
    
        return ...
    }
    
    0 讨论(0)
  • 2020-12-17 09:10

    I got this using material UI by trying to do const searchParams = new URLSearchParams(process.browser ? window.location.search : '') at the top of the react component in my NextJS app with material-ui SnackBar, I was able to remove the error by putting this in a useEffect hook.

    Entire component for reference:

    export default function SnackBarMessage() {
      const [requestLogin, setRequestLogin] = useState(false)
      const handleClose = (event, reason) => {
        if (reason === 'clickaway') {
          return
        }
    
        setRequestLogin(false)
      }
    
      useEffect(() => {
        // had to move into a useEffect hook
        const searchParams = new URLSearchParams(process.browser ? window.location.search : '')
        const hasRequestLogin = Boolean(searchParams.get('requestLogin'))
        if (hasRequestLogin) {
          setRequestLogin(true)
        }
      }, [])
      return (
        <>
          {requestLogin && (
            <Snackbar open={requestLogin} autoHideDuration={6000} onClose={handleClose}>
              <Alert onClose={handleClose} severity='error' style={{ fontSize: '18px' }} elevation={6}>
                Please Log Back In
              </Alert>
            </Snackbar>
          )}
        </>
      )
    }
    
    0 讨论(0)
  • 2020-12-17 09:12

    In my case it was because of using PersistGate and react-loadable. if you using this libraries, you could use preloadAll instead of preloadReady

    0 讨论(0)
  • 2020-12-17 09:13

    This seems to be because of Browsersync inserting a script tag in the body on client side that does not exist on server side. Thus React fails to attach to the server render.

    0 讨论(0)
  • 2020-12-17 09:13

    In my case i installed REACTFUL and it do a render so different by default install:

    src/renderers/dom.js

    ReactDOM.hydrate(
      <App initialData={window.__R_DATA.initialData} />,
      document.getElementById('root'),
    );
    

    src/renderers/server.js

    const initialData = {
       appName: 'Reactful',
     };
    return Promise.resolve({
       initialData,
       initialMarkup: ReactDOMServer.renderToString(
         <App initialData={initialData} />,
       ),
       pageData,
     });
    

    care with initialData!

    i fix it changed dom.js like it, attention to initialData is important:

    const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate;
    const initialData = {
      appName: 'Reactful',
    };
    renderMethod(
      <App initialData={initialData} />,
      document.getElementById('root'),
    );
    
    0 讨论(0)
  • 2020-12-17 09:19

    If your HTML code is like

    <table>
      <tr>
    

    you can get this error.
    To get around it, use the <tbody> tag like

    <table>
      <tbody>
        <tr>
    

    Don't forget to close the tag(s)!

    0 讨论(0)
提交回复
热议问题