首页 > 解决方案 > React 服务器端只渲染特定的路由

问题描述

我目前有一个使用 EJS 构建的网站,并在 port 的后端使用 express 3300。路由的结构如下所示:

localhost:3300
-/movies
   -/rating
   -/review
-/tvshows
   -/rating
   -/review

我目前在这样的路线中返回 EJS 文件:

router.get("/:title/rating", function(req, res) {
    Movie.find({ movieName: req.params.title })
    .exec(function(err, foundMovie) {
        if (err) {
            console.log(err);
        } else {
            console.log(foundMovie)
            res.render("movie/rating", { movie: foundMovie});        
        }
    });
});

但是现在,我想在使用 React 的结构中添加一个新路由,以便使用 React 构建以下内容:

localhost:3300
-/documentary
    -/rating
    -/review

据我了解,如果我想使用 React,我将不得不将我以前的所有路由(返回 EJS)重写为 React 组件,因为您无法合并两个服务器(React 和 Express,因为它们都在不同的端口上运行:30003300分别)。但是由于我已经写了这么多,我尝试按照本教程在服务器端呈现新路由,结果是:

router.get("/documentary", (req,res) => {
    Documentary.find({}).exec(function(err,foundDoc){
        if (err){
            console.log(err);
        } else {
            fs.readFile(path.resolve("./views/react/client/build/index.html"), "utf-8", (err, data) => {
                if (err) {
                  return res.status(500).send("Error");
                }
                return res.send(
                  data.replace(
                    '<div id="root"></div>',
                    `<div id="root">${ReactDOMServer.renderToString(<App />)}</div>`
                  )
                );
              });
        }
    })
});

App.js 看起来像:

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/rating">
          <h1>Rating page for Documentaries</h1>
        </Route>  
        <Route exact path="/review">
          <h1>Review page for Documentaries</h1>
        </Route>
      </Switch>
    </BrowserRouter>
      );
    }

我收到一个错误: Error: Invariant failed: Browser history needs a DOM at invariant

如何修复错误?或者有没有更好的方法来结合 EJS 路由并创建新的 React 路由?提前致谢

标签: javascriptreactjsexpressreact-routerejs

解决方案


问题

您还需要Router在服务器中使用不同的。由于BrowserRouter在客户端 React 应用程序无法在服务器中处理。

静态路由器是您正在寻找的。

解决方案

服务器端渲染React非常棘手。我建议您使用Nextjs,这很容易。

对于side-projects请参阅此博客


推荐阅读