Javascript React SSR:未定义文档

Javascript React SSR:未定义文档,javascript,reactjs,webpack,material-ui,server-side-rendering,Javascript,Reactjs,Webpack,Material Ui,Server Side Rendering,我已经为此工作了两天了。查看了多个堆栈帖子,仍然没有找到合适的答案 我正在尝试在服务器中呈现我的react项目,如下所示: Server.js function handleRender(req,res){ const sheetsRegistry = new SheetsRegistry(); const sheetsManager = new Map(); const theme = createMuiTheme({ palette:{ primary:

我已经为此工作了两天了。查看了多个堆栈帖子,仍然没有找到合适的答案

我正在尝试在服务器中呈现我的react项目,如下所示:

Server.js

function handleRender(req,res){

  const sheetsRegistry = new SheetsRegistry();

  const sheetsManager = new Map();

  const theme = createMuiTheme({
    palette:{
      primary:green,
      accent: red,
      type: 'light',
    }
  })

  const generateClassName = createGenerateClassName();

  const html = ReactDOMServer.renderToString(
    <JssProvider registry={sheetsRegistry} generateClassName={generateClassName}>
      <MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
        <TwoFA />
      </MuiThemeProvider>
    </JssProvider>
  )

  const css = sheetsRegistry.toString()

  res.send(renderFullPage(html,css))
}

function renderFullPage(html,css){
  return   `
    <!DOCTYPE html>
    <html>
      <head>
        <title>2FA SDK</title>
      </head>
      <body style="margin:0">
        <div id="app">${html}</div>
        <script id="jss-server-side">${css}</script>
      </body>
    </html>
  `
}
module.exports = [
    {
        /*Config for backend code*/ 
        entry: './src/server/server.js',
        output: {
            filename: 'server.js'
        },
        externals: [nodeExternals()],
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: {
                        loader: "babel-loader"
                    }
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: "html-loader",
                        options: { minimize: true }
                    }
                },
                {
                    test: /\.css$/,
                    use: [MiniCssExtractPlugin.loader,"css-loader"]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: "./public/index.html",
                filename:"./index.html"
            }),
            new MiniCssExtractPlugin({
                filename: "[name].css",
                chunkFilename:"[id].css"
            })
        ]
    },
    { 
        entry: './src/client.js',
        output: {
           filename: 'bundle.js',
        },
        module: {
           rules: [
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: "html-loader",
                        options: { minimize: true }
                    }
                },
                {
                    test: /\.css$/,
                    use: [MiniCssExtractPlugin.loader,"css-loader"]
                }
            ],
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: "./public/index.html",
                filename:"./index.html"
            }),
            new MiniCssExtractPlugin({
                filename: "[name].css",
                chunkFilename:"[id].css"
            })
        ]
    }
]
我尝试过的:我在SO上搜索,发现许多帖子建议进行如下条件检查:
if(typeof window!=='undefined')
。然而,这并不能解决问题

我还了解到错误是由于在SSR期间,服务器端没有文档项目

我在github问题页面上搜索过,有人提到他在webpack上遇到了问题,但同一个项目在browserify上运行良好

我需要帮助的内容:我正在尝试解决此问题,因为它会导致应用程序崩溃


我怀疑网页包有问题。我正在寻找解决此问题的方法。此问题通常发生在服务器上呈现react时。服务器端没有文档或窗口对象,这些对象仅在浏览器上可用

尝试在
componentDidMount
中或之后调用文档函数

componentDidMount(){
  this.setState({documentLoaded:true});
}

someFunction(){
  const { documentLoaded } = this.state;
  if(documentLoaded){
     // LOGIC USING DOCUMENT OBJECT
  }
}

如果您使用的是react钩子,则可以创建自定义useDocument钩子:

import React, { useEffect, useState } from 'react'

export const useDocument = () => {
  const [myDocument, setMyDocument] = useState(null)
   
  useEffect(() => {
    setMyDocument(document)
  }, [])

  return myDocument
}
在您的组件中:

...
const doc = useDocument()
...

<SomeComponent
 ref={doc && doc.body}
 ...
/>
...
。。。
const doc=useDocument()
...
...

MiniCssExtractPlugin
可能是罪魁祸首
...
const doc = useDocument()
...

<SomeComponent
 ref={doc && doc.body}
 ...
/>
...