gpt4 book ai didi

react-router-v4 - react-router 4-浏览器历史记录需要一个DOM

转载 作者:行者123 更新时间:2023-12-03 11:57:39 25 4
gpt4 key购买 nike

我正在尝试使用react-router 4进行服务器端渲染。我正在按照此处提供的示例https://reacttraining.com/react-router/web/guides/server-rendering/putting-it-all-together

按照服务器上的示例,我们应该使用StaticRouter。当我按照示例导入时,我看到StaticRouter为未定义

import {StaticRouter} from 'react-router';

在网上进行了一些研究之后,我发现我可以使用 react-router-dom。现在我的导入语句看起来像这样。
import {StaticRouter} from 'react-router-dom';

但是,当我运行代码时,我在浏览器中得到了 Invariant Violation: Browser history needs a DOM

我的server.js文件代码
....
app.get( '*', ( req, res ) => {
const html = fs.readFileSync(path.resolve(__dirname, '../index.html')).toString();
const context = {};
const markup = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context} >
<App/>
</StaticRouter>
);

if (context.url) {
res.writeHead(302, {
Location: context.url
})
res.end();
} else {
res.send(html.replace('$react', markup));
}
} );
....

还有我的client / index.js代码
....
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), root);
....

更新v1
将我的示例减少到最小的负担,并且仍然出现相同的错误。

clientIndex.js
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from '../App'

ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
), document.getElementById('app'))

serverIndex.js
import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'
import App from '../App'

createServer((req, res) => {
const context = {}

const html = ReactDOMServer.renderToString(
<StaticRouter
location={req.url}
context={context}
>
<App/>
</StaticRouter>
)

res.write(`
<!doctype html>
<div id="app">${html}</div>
`)
res.end()
}).listen(3000);

App.js
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import routes from "./client/routes";
const App = ( ) => (
<Router>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>
)

export default App;

最佳答案

您需要使用其他历史记录提供程序进行服务器端渲染,因为服务器上没有真正的DOM(和浏览器的历史记录)。因此,在您的app.js中用Router和备用历史记录提供程序替换BrowserRouter可以解决此问题。另外,您不必使用两个包装器。您在app.js和clientIndex.js中两次使用BrowserRouter,这是不必要的。

import { Route, Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';

const history = createMemoryHistory();

<Router history={history}>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>

现在,您可以用ConnectedRouter替换StaticRouter,后者可以在客户端和服务器中使用。我使用以下代码在历史记录之间进行选择并导出以在ConnectedRouter的历史记录中使用。
export default (url = '/') => {
// Create a history depending on the environment
const history = isServer
? createMemoryHistory({
initialEntries: [url]
})
: createBrowserHistory();
}

关于react-router-v4 - react-router 4-浏览器历史记录需要一个DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43058684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com