|
1 | 1 | import * as React from 'react';
|
2 | 2 | import { Provider } from 'react-redux';
|
3 | 3 | import { renderToString } from 'react-dom/server';
|
4 |
| -import { match, RouterContext } from 'react-router'; |
5 |
| -import createMemoryHistory from 'history/lib/createMemoryHistory'; |
| 4 | +import { StaticRouter } from 'react-router-dom'; |
| 5 | +import { replace } from "react-router-redux"; |
| 6 | +import { createMemoryHistory } from 'history'; |
6 | 7 | import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
|
7 | 8 | import routes from './routes';
|
8 | 9 | import configureStore from './configureStore';
|
9 | 10 |
|
10 | 11 | export default createServerRenderer(params => {
|
11 | 12 | return new Promise<RenderResult>((resolve, reject) => {
|
12 |
| - // Match the incoming request against the list of client-side routes |
13 |
| - const store = configureStore(); |
14 |
| - match({ routes, location: params.location }, (error, redirectLocation, renderProps: any) => { |
15 |
| - if (error) { |
16 |
| - throw error; |
17 |
| - } |
| 13 | + // Create memory history to use in the Redux store |
| 14 | + const history = createMemoryHistory(); |
| 15 | + const store = configureStore(history); |
18 | 16 |
|
19 |
| - // If there's a redirection, just send this information back to the host application |
20 |
| - if (redirectLocation) { |
21 |
| - resolve({ redirectUrl: redirectLocation.pathname }); |
22 |
| - return; |
23 |
| - } |
| 17 | + // Dispatch the current location so that the router knows where to go |
| 18 | + store.dispatch(replace(params.location)); |
24 | 19 |
|
25 |
| - // If it didn't match any route, renderProps will be undefined |
26 |
| - if (!renderProps) { |
27 |
| - throw new Error(`The location '${ params.url }' doesn't match any route configured in react-router.`); |
28 |
| - } |
| 20 | + const context : any = {}; |
29 | 21 |
|
30 |
| - // Build an instance of the application |
31 |
| - const app = ( |
32 |
| - <Provider store={ store }> |
33 |
| - <RouterContext {...renderProps} /> |
34 |
| - </Provider> |
35 |
| - ); |
| 22 | + const app = ( |
| 23 | + <Provider store={ store }> |
| 24 | + <StaticRouter context={ context } location={ params.location.path } children={ routes } /> |
| 25 | + </Provider> |
| 26 | + ); |
36 | 27 |
|
37 |
| - // Perform an initial render that will cause any async tasks (e.g., data access) to begin |
38 |
| - renderToString(app); |
| 28 | + // Perform an initial render that will cause any async tasks (e.g., data access) to begin |
| 29 | + renderToString(app); |
39 | 30 |
|
40 |
| - // Once the tasks are done, we can perform the final render |
41 |
| - // We also send the redux store state, so the client can continue execution where the server left off |
42 |
| - params.domainTasks.then(() => { |
43 |
| - resolve({ |
44 |
| - html: renderToString(app), |
45 |
| - globals: { initialReduxState: store.getState() } |
46 |
| - }); |
47 |
| - }, reject); // Also propagate any errors back into the host application |
48 |
| - }); |
| 31 | + // If there's a redirection, just send this information back to the host application (Maybe improve this?) |
| 32 | + if (context.url) { |
| 33 | + resolve({ redirectUrl: context.url }); |
| 34 | + return; |
| 35 | + } |
| 36 | + |
| 37 | + // Once the tasks are done, we can perform the final render |
| 38 | + // We also send the redux store state, so the client can continue execution where the server left off |
| 39 | + params.domainTasks.then(() => { |
| 40 | + resolve({ |
| 41 | + html: renderToString(app), |
| 42 | + globals: { initialReduxState: store.getState() } |
| 43 | + }); |
| 44 | + }, reject); // Also propagate any errors back into the host application |
49 | 45 | });
|
50 | 46 | });
|
0 commit comments