我正在使用带有服务器端渲染功能的React创建博客应用程序。我使用Create React App创建应用程序。
我遇到一个问题,即我的服务器数据被渲染一秒钟,然后在React接管渲染过程后消失了。我正在使用React Router Dom将数据从服务器传递到客户端react。基本上,我是按照本教程创建应用程序https://www.youtube.com/watch?v=NwyQONeqRXA的,但是视频缺少一些信息,例如获取API上的数据。因此,我引用此存储库以获取有关API https://github.com/tylermcginnis/rrssr
的数据基于我收集的资源,我最终得到了以下代码。
server.js
import express from "express";
import fs from "fs";
import path from "path";
import { StaticRouter, matchPath } from "react-router-dom";
import React from "react";
import ReactDOMServer from "react-dom/server";
import serialize from "serialize-javascript";
import App from "../src/App";
import routes from "../src/routes";
const app = express();
const PORT = 3001;
app.use(express.static(path.resolve(__dirname, "..", "build")));
app.get("*", (req, res, next) => {
// point to the html file created by CRA's build tool
const filePath = path.resolve(__dirname, "..", "build", "index.html");
fs.readFile(
path.resolve(filePath),
"utf-8",
(err, html_data) => {
if (err) {
console.error(err);
return res.status(500).send(`Some error happened: ${err}`);
}
const activeRoute =
routes.find(route => matchPath(req.url, route)) || {};
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve();
promise
.then(rawData => {
console.log('rawData', rawData[0]);
const context = { posts: rawData };
const markup = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
return res
.status(200)
.send(
html_data
.replace(
'<div id="root" class="container-fluid"></div>',
`<div id="root" class="container-fluid">${markup}</div>`
)
.replace(
"__INITIAL_DATA__={}",
`__INITIAL_DATA__=${serialize(rawData)}`
)
);
})
.catch(next);
}
);
});
app.listen(PORT, () => {
console.log(`App launched at http://localhost:${PORT}`);
});
Node JS Server入口点index.js
require("ignore-styles");
require("@babel/register")({
ignore: [/(node_modules)/],
presets: ["@babel/preset-env", "@babel/preset-react"]
});
require("./server");
客户端反应index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.css";
import "./index.css";
import "./fonts/VarelaRound-Regular.ttf";
ReactDOM.hydrate(
<BrowserRouter>
<App post_data={window.__INITIAL_DATA__} />
</BrowserRouter>,
document.getElementById("root")
);
Clieant反应App.js
import React, { Component } from "react";
import "./App.css";
import { Route, Link, Redirect, Switch } from "react-router-dom";
import routes from "./routes";
class App extends Component {
render() {
return (
<div>
<Switch>
{routes.map(
({ path, exact, component: Component, ...rest }) => (
<Route
key={path}
path={path}
exact={exact}
render={props => (
<Component {...props} {...rest} />
)}
/>
)
)}
</Switch>
</div>
);
}
}
export default App;
当我尝试在组件上输出数据时,它消失了,现在服务器上的staticContext传递未定义。这里似乎是什么问题?我是否缺少某些配置或库?
import React from "react";
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: this.props.staticContext
? this.props.staticContext.posts
: []
};
console.log("constructor", this.props); // STATIC CONTEXT UNDEFINED ON THIS OUTPUT
}
componentDidMount() {
console.log("componentDidMount", this.props);// STATIC CONTEXT UNDEFINED ON THIS OUTPUT
}
}