我正在使用React.js并为我的应用程序表达。我正在尝试为该应用设置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)
谢谢!
答案 0 :(得分:0)
您需要正确设置。两者互不相同。 React是客户端应用程序,而Express是服务器应用程序。
看看Sandeep Raveesh's post,然后尝试boilerplate。它可以帮助您理解它。
答案 1 :(得分:0)
@Tholle的回答帮助我解决了这个问题。
https://reacttraining.com/react-router/web/guides/server-rendering