Here is my problem,
- I have a front server (apache or nginx) and had some configs like proxy_pass "iamurl/server_render/" to "backend.iamurl.com:3000/".
- I have a server rendering react-router programme running on the "backend.iamurl.com:3000" server. (react ,react-router, koa2 and redux).
- When I run it on the client side everything is right.
- When I run it on the server side, at the first time the request on the server (koa2),i get ctx.url = / so the router matched. But when renderToString() finish and the client had received the response, the location.path is "/server_render", so react-router does't render what i want.
I know the problem is different path on the client- and server-side, but I think this situation(using proxy) is very common in the big company. How can I run correct when the browser received the server rendering response?
I am looking for everyone's idea.
my routes code (share between client and server side)
<Route path='/' component={Connector}>
<Route component={BaseLayout}>
<IndexRoute components={Home} onEnter={onRouteChange.bind(this, 'home')}/>
<Route path="articleDetail/:id" components={ArticleDetail} onEnter={onRouteChange.bind(this, 'home')}/>
<Route path="about" components={About} onEnter={onRouteChange.bind(this, 'about')}/>
<Route path="joinUs" components={JoinUs} onEnter={onRouteChange.bind(this, 'JoinUs')}/>
</Route>
</Route>
here is my server rendering code
async function serverRender(ctx, next, renderProps) {
return new Promise((resolve, reject) => {
fetchArticlesAPI({API_URL, page: 1}, apiResult => {
const homeReducer = {
"home": {
fetched: true,
data: apiResult.dataList,
times: 1,
page: 1
}
};
const preloadedState = {"home": homeReducer.home};
const store = createStore(rootReducer, preloadedState);
const html = renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
);
const finalState = store.getState();
const finalStateToClient = JSON.stringify(finalState).replace(/</g, '\\x3c');
const body = ctx.render('index', {
title: "盘古首页(同构)",
dev: argv.env === 'development',
finalStateToClient,
html
});
resolve(body);
});
});
}
export default async (ctx, next) => {
const {redirectLocation, renderProps} = await _match({routes: routes, location: ctx.url});
if (redirectLocation) {
ctx.redirect(redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
await serverRender(ctx, next, renderProps)
} else {
await next()
}
}