React路由器-浏览器历史需要一个dom



我正在为我的应用程序使用React.js和express。我正在尝试为应用程序设置react路由器dom。

然而,当我尝试运行该应用程序时,我会收到警告:

Invariant Violation: Browser history needs a DOM
at invariant (/home/jshen/playlistTracker/node_modules/invariant/invariant.js:40:15)
at createBrowserHistory (/home/jshen/playlistTracker/node_modules/history/createBrowserHistory.js:49:27)
at new BrowserRouter (/home/jshen/playlistTracker/node_modules/react-router-dom/BrowserRouter.js:46:197)
at processChild (/home/jshen/playlistTracker/node_modules/react-dom/cjs/react-dom-server.node.development.js:2095:14)
at resolve (/home/jshen/playlistTracker/node_modules/react-dom/cjs/react-dom-server.node.development.js:2061:5)
at ReactDOMServerRenderer.render (/home/jshen/playlistTracker/node_modules/react-dom/cjs/react-dom-server.node.development.js:2380:22)
at ReactDOMServerRenderer.read (/home/jshen/playlistTracker/node_modules/react-dom/cjs/react-dom-server.node.development.js:2354:19)
at renderToString (/home/jshen/playlistTracker/node_modules/react-dom/cjs/react-dom-server.node.development.js:2726:25)
at handleRender (/home/jshen/playlistTracker/dist/server.js:755:41)
at Layer.handle [as handle_request] (/home/jshen/playlistTracker/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/jshen/playlistTracker/node_modules/express/lib/router/index.js:317:13)
at /home/jshen/playlistTracker/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/jshen/playlistTracker/node_modules/express/lib/router/index.js:335:12)
at next (/home/jshen/playlistTracker/node_modules/express/lib/router/index.js:275:10)
at expressInit (/home/jshen/playlistTracker/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/home/jshen/playlistTracker/node_modules/express/lib/router/layer.js:95:5)

应用程序.jsx

import React, {Component, Fragment} from 'react';
import {BrowserRouter, Switch, Route } from 'react-router-dom'
import { NavBar } from './layouts'
import Main from './main'
class App extends Component {
constructor(props){
super(props);
this.state = {
currentUser: {name: "testUser"},
favourite: [],
playlist: []
};
}
render() {
return (
<BrowserRouter>
<NavBar>
<Switch>
<Route exact path ="/" render={
() => <div> hello </div>
}/>
</Switch>
</NavBar>
</BrowserRouter>
)
}
}
export default App;

server.js

import express from 'express';
import React from 'react';
import App from '../client/App.jsx';
import { renderToString } from 'react-dom/server'
import { SheetsRegistry } from 'react-jss/lib/jss'
import JssProvider from 'react-jss/lib/JssProvider'
import {
MuiThemeProvider,
createMuiTheme,
createGenerateClassName,
} from '@material-ui/core/styles'
const app = express();
const port = 3000;
// This is fired every time the server side receives a request.
app.use(handleRender);
app.listen(port);
// inject our initial component HTML and CSS into a template to be rendered on the client side.
function renderFullPage(html, css) {
return `
<!doctype html>
<html>
<head>
<title>Material-UI</title>
</head>
<body>
<div id="root">${html}</div>
<style id="jss-server-side">${css}</style>
</body>
</html>
`;
}
// When rendering, we will wrap App, our root component, inside a JssProvider and MuiThemeProvider 
// to make the sheetsRegistry and the theme available to all components in the component tree.
// Render the initial HTML of our component before we send it to the client side. 
// To do this, we use ReactDOMServer.renderToString().
function handleRender(req, res) {
// Create a sheetsRegistry instance.
const sheetsRegistry = new SheetsRegistry();
// Create a theme instance.
const theme = createMuiTheme({
palette: {
primary: {
light: '#757575',
main: '#a4a4a4',
dark: '#494949',
contrastText: '#ffffff',
},
secondary: {
light: '#263238',
main: '#a4a4a4',
dark: '#494949',
contrastText: '#ffffff',
},
// accent: red,
// type: 'light',
},
});
const generateClassName = createGenerateClassName();
// Render the component to a string.
const html = renderToString(
<JssProvider registry={sheetsRegistry} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme} sheetsManager={new Map()}>
<App />
</MuiThemeProvider>
</JssProvider>
)
// Grab the CSS from our sheetsRegistry.
const css = sheetsRegistry.toString()
// Send the rendered page back to the client.
res.send(renderFullPage(html, css))
}

不知道我错过了什么。我想这可能是由于服务器端的某些原因,但无法解决。

我读到这可能是由于历史组件的原因。然而,我看到了它只与BrowserRouter一起工作的例子。(例如。https://github.com/jsmegatools/React-online-course/tree/master/Lesson-2)

谢谢!

您需要正确设置它。他们两个彼此不同。React是客户端应用程序,而Express是服务器应用程序。

看看Sandeep Raveesh的帖子,试试样板。它可能会帮助你理解它。

@Tholle的回答帮助我解决了这个问题。

https://reacttraining.com/react-router/web/guides/server-rendering

最新更新