You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Fixes#239, fixes#240
- Refactors ChallengeCard component (splits out NumRegistrants and
NumSubmissions components, with related logic, into separate
components).
- Improves How To Deep-Link doc.
Copy file name to clipboardExpand all lines: docs/how-to-deep-link.md
+19-14Lines changed: 19 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ For some page you want to expose its state (or part of the state) via URL query
6
6
- When that URL is used to access the app, the page is opened with the state described by the URL query params.
7
7
8
8
### Solution
9
-
The key idea is simple: internally, you still use Redux actions / reducers / store to describe and modify entire state of the page. Inside reducer's action handlers, related to that parts of the state, that you want to expose via URL query, you add the code to properly update URL each time reducer re-evaluates related pieces of the state. Inside that reducer's factory you, in case of server-side rendering, check query parameters of HTTP request and create proper intial state of Redux store. To navigate around the app / change the page state from within the app, you just dispatch related actions, URL will be automatically updated by reducers. **In the cases when you programmatically change the route inside the app, using react-router, related actions should be dispatched after transition, as explained below**.
9
+
The key idea is simple: internally, you still use Redux actions / reducers / store to describe and modify entire state of the page. Inside reducer's action handlers, related to that parts of the state, that you want to expose via URL query, you add the code to properly update URL each time reducer re-evaluates related pieces of the state. Inside that reducer's factory you, in case of server-side rendering, check query parameters of HTTP request and create proper intial state of Redux store. To change the page state without transition between pages, you just dispatch related actions, the URL will be automatically updated. **In the cases when you programmatically change the route inside the app, using react-router, related actions should be dispatched after transition, as explained below**.
10
10
11
11
### Examples
12
12
At the moment of writing this instruction, this approach is used inside challenge listings to expose challenge filters and selected buckets via URL query; and also within challenge details page to expose different detail tabs. The implementation notes below will refer to the second usage.
@@ -43,19 +43,24 @@ At the moment of writing this instruction, this approach is used inside challeng
43
43
44
44
- To make a transition to the page, from another route within the app, and select the desired tab you:
45
45
- As usually use `<Link>` component from `react-router` to make transition (in our codebase we have an auxiliary wrapper around it in [`utils/router` module](https://github.com/topcoder-platform/community-app/blob/develop/src/shared/utils/router/index.jsx), also the standard [buttons](https://github.com/topcoder-platform/community-app/tree/develop/src/shared/components/buttons) and [tags](https://github.com/topcoder-platform/community-app/tree/develop/src/shared/components/tags) are rendered as `react-router``<Link>`s when appropriate; the idea stay the same if you use it);
46
-
- In `to` prop you pass the target endpoint without query params (specifying query params within this prop makes no sense: it will update the URL, but won't update Redux state properly).
47
-
- Inside `onClick` prop you dispatch necessary action(s), wrapped inside `setImmediate(..)` method. For example, to move from the challenge listing to the challenge details page of a challenge with ID 12345, and with winners tab open (provided that the challenge is completed and thus it is appopriate to link to that tab) you do something like this:
48
-
```jsx
49
-
<Link
50
-
onClick={() =>
51
-
setImmediate(() =>selectTab('winners'))
52
-
}
53
-
to="/challenges/12345"
54
-
>Winners</Link>
55
-
```
56
-
where `selectTab(..)` function is mapped to the corresponding action within page (component) container.
57
-
58
-
`setImmediate(..)` is necessary here to delay update Redux store after the endpoint transition is handled by `react-redux`; because of `to="/challenges/12345"``react-redux` will remove any query params from URL. The `onClick` callback, when wrapped inside `setImmediate(..)` will be triggered right after the transition, it will properly update Redux state, and set the correct URL query. From visitor's point of view it happens with no pause in beween (i.e. when the page is loaded he already will see the target tab).
46
+
47
+
-`to` prop of `<Link>` specifies target route (and query params, if specified) for `react-router`. It does not update Redux state, so you should also supply `onClick` prop, which will dispatch all necessary actions:
48
+
```js
49
+
<Link
50
+
onClick={() =>selectTab('winners')}
51
+
to="/challenges/12345?tab=winners"
52
+
>
53
+
```
54
+
where `selectTab(..)`function is mapped to the corresponding action within page (component) container.
55
+
56
+
- It is important to note that in the code above, transition between the routes is handled by `react-router` after the moment `selectTab(..)` is triggered and handled by reducers; thus, the query params written to URL by reducers will be overriden by those you specify inside `to` prop. It means, if you make a mistake and provide a wrong query there, it will be out of sync with the actual state of the page after transition. As an alternative, you can do
In this case `selectTab(..)` will be triggered after transition, thus reducers will take care about proper query params written inURL. However, you still want to leave correct query inside `to`, because when user copies a link with right mouse button, or open it in a newpage, he will get the URL specified there there.
59
64
60
65
### Caveats
61
66
- When you read url query params at the server side, any array with20 and more elements will be parsed as an object with keys equal to array element indices. Under the hood it is done by [qs](https://www.npmjs.com/package/qs) module on purpose. Don't try to reconfigure `qs`, just remember that you can get an object when you expect an array, and handle that situation correctly.
0 commit comments