forgeplus-react/server/render.js

94 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import {renderToString} from "react-dom/server";
import {StaticRouter, matchPath} from "react-router-dom";
import {renderRoutes} from "react-router-config";
import Routes, { deepRoutes } from "../Routes";
import { Provider } from "react-redux";
import { getPathType } from './service'
import { serverStore } from "../src/redux/stores/configureStore";
import App from "../src/App";
import { Route } from 'react-router-dom';
import { setDefaultMeta } from '../src/common/UrlTool'
export const render = async (req,res)=>{
let _route = null,
_match = null;
let store = serverStore();
function matchSubRoutes(routes, url) {
for (const route of routes) {
// 检查当前路由是否匹配
let match = matchPath(url, route.path);
if (match) {
// 如果当前路由匹配,并且它有子路由,递归检查子路由
if (route.routes) {
// 递归调用匹配子路由
const subMatch = matchSubRoutes(route.routes, url);
if (subMatch) {
_route = route;
_match = subMatch;
return true;
}
}
// 如果没有子路由,或者子路由不匹配,但当前路由匹配,返回当前路由
_route = route;
_match = match;
return true;
}
}
// 如果没有找到匹配的路由返回false
return false;
}
matchSubRoutes(deepRoutes, req.url.split("?")[0])
let context = {
code: 200,
};
if (_route && _route.component && _route.component.preFetch) {
context = await _route.component.preFetch({
store,
match: _match,
query: req.path,
});
}
const content = renderToString((
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
<Route path='/:owner/:projectsId' exact component={App}></Route>
</StaticRouter>
</Provider>
))
if (!content) {
// 未匹配到详情页恢复默认header
setDefaultMeta()
} else {
// 匹配到服务端渲染页面注入state
let script = domObj.window.document.getElementById('initState')
if (!script) {
script = domObj.window.document.createElement('script')
script.setAttribute('id', 'initState')
}
script.textContent = `window.__initState__ = ${ JSON.stringify(store.getState()) }`
domObj.window.document.head.appendChild(script);
}
let html = domObj.serialize()
const prepHTML=(data,rootString)=>{
data=data.replace('<div id="root" class="page -layout-v -fit widthunit"></div>',`<div id="root" class="page -layout-v -fit widthunit">${rootString}</div>`);
return data;
}
res.send(prepHTML(html, content))
store = null
}