【发布时间】:2018-12-26 23:04:00
【问题描述】:
我正在为我的应用程序使用 React.js 和 express。我正在尝试为应用程序设置 react-router-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)
App.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))
}
无法弄清楚我错过了什么。我认为这可能是由于服务器端的某些原因,但无法弄清楚。
我已经读到这可能是由于历史组件造成的。但是,我已经看到了仅使用 BrowerRouter 的示例。(例如https://github.com/jsmegatools/React-online-course/tree/master/Lesson-2)
谢谢!
【问题讨论】:
-
你不应该在服务器上导入和使用
BrowserRouter,因为服务器上没有DOM。 This guide might give some inspiration. -
@Tholle,谢谢!该指南对我帮助很大
标签: javascript reactjs express react-router material-ui