-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor frontend routing to react-router #5711
Comments
react-router PoC: https://gist.github.com/chillu/b1cdda9b49d98a257aae1ba8cd4d174b |
We're initialising the react-router So just in case we need a |
Regarding react-router vs. redux: Take the This is a different approach to the While the new approach looks cleaner on the surface, it has a serious limitation: Since Another use case is closing the While react-router-redux stores params in the So I'm back at square one with this ... https://github.com/acdlite/redux-router would solve the issue, but it's unclear if choosing this library is sustainable (discussion). And once we solved the issue of getting route state into the store, we then also have to solve how we sync any state changes back to the url (current approach: https://github.com/silverstripe/silverstripe-asset-admin/blob/73fa20c361c275a81ff57e4b5b02c338086f3b83/client/src/containers/AssetAdmin/AssetAdmin.js#L76) |
@unclecheese @assertchris Any insights on the react-router vs. redux conundrum above? :) |
See silverstripe#5711 Refactor lib/RouteRegistry to nested react-router registration
See silverstripe#5711 Refactor lib/RouteRegistry to nested react-router registration
Yes it is in redux store. It's in the routing store, managed via react-routing-redux. This property is made available to components via react-redux-router syncing with react-router history object, which parses and populates the component properties. This behaviour acts in PLACE of connect() mapping state to props directly, but it does the same thing, albeit with react-routing (and thus the browser bar) as an intermediary. However, this doesn't mean that the state isn't the source of truth. Time travel actions are synced from the store automatically by react-route-redux, so us trying to layer another state on top of that is redundant. |
See silverstripe#5711 Refactor lib/RouteRegistry to nested react-router registration
I think it comes down to how much knowledge we want third party components to have about our application structure. Contrived example: A third party CMS module adds a better way to inline search across all files, but showing files in the current folder first. Currently this component can't just look in the Redux state for the "current folder", because its passed down from react-router directly into the component hierarchy as a prop. This is different from other UI state like "currently selected files", which is in the Redux state. Given that such a React component needs to be part of the existing component hierarchy (e.g. "injected" into We're also spreading knowledge of the application routing: If that new inline search wanted to close any active sidebars before displaying results, it would have to know that's done by changing the route ( This line here is the point of contention: You close the file sidebar by routing to the folder view, rather than And the "selected files" Redux state is just kept in sync because its manually triggered by the component observing prop changes. This makes state transitions harder to debug than following side effects caused by actions ( Sure, there's one source of truth for state in the current implementation, but I'm worried that it'll create an unmaintainable system if you think about the amount of components relying on the concept of a "current record" throughout different CMS interfaces. Given that even the authors of Redux are struggling with doing this cleanly (reduxjs/redux#227 (comment)), I'll let it go for now - let's see if it becomes a problem in practice before overengineering :) Related: RFC-9 UI Extensibility |
The current page.js based routing was a "least common denominator approach", where routing functionality was stripped back to simple callback handling. See #5243 for context. The rationale was that a react based router couldn't handle Entwine/PJAX based legacy sections cleanly. This has caused a lot of work in the last week, combined with a lot of learning about how routing should influence views and redux state.
Some disadvantages:
AssetGalleryField
was designed as a standalone, "semi-Entwine" component with its own React root initialisation based on Entwine matching, and its own redux state. This doesn't fit into the bigger picture of how we want the different UIs to work togetherswitch(this.props.view)
conditional inAssetAdmin
is a good example)page.start()
), but there's no introspection into existing routes which can be limiting for customisation. With react-router, we can keep all routes in an SS-managed registry and pull them on demand.We're attempting to get react-router into core as an optional router which just kicks in for new react-based sections. We might use react-router-redux (not redux-router since its fallen out of favour). It's technically not required at the moment (we can pass
props.params
through to children components), but seems likely to be required for any additional components from third party extensions, since those won't have easy access toprops.params
(note that redux-router recommends not to use this redux state directly though).Branches:
https://github.com/open-sausages/silverstripe-framework/tree/pulls/4.0/react-router
https://github.com/open-sausages/silverstripe-asset-admin/tree/pulls/4.0/react-router
Tasks
lib/RouteRegister
to work with react-router config instead of callbacksframework
intoFormBuilder
Separate out(we removed AssetGalleryField instead, not relying on form schema for this part)AssetGalleryField
logic fromAssetAdmin
container so it can be lazy loaded viaFormBuilder
Lazy registration of(no longer required since we removed that indirection)admin/assets/show/:folderId/edit/:fileId
route viaAssetGalleryField
Editor
through react-router as a childRoute ofAssetGalleryField
Re-match route onceAssetGalleryField
has lazy registered routes (might need to showEditor
component):folderId
and:fileId
props for view initialisationAssetAdmin
init on jQuery.entwine, useFormBuilder
insteadrouter.show()
calls throughout CMSbrowserHistory.push()
instead ofrouter.show()
inCampaignAdmin
andAssetAdmin
(docs)propTypes
on all componentsThings that block merge:
react-router-redux
(Ingo's working this now) to populate redux state from URL (albeit asynchronously so can only be read at certain times)Sync back Redux state into route, and identify legal times to read react-router-redux state (see current implementation through refreshUrl), and rationale from Redux creatorPulled out into Minor: review handling of redux state with react-router. #5797If "Sync back Redux state into route" is a dead end: Ensure that all existing reducers are accessing router params and not legacy state values (Pulled out into Minor: review handling of redux state with react-router. #5797state.gallery.fileId
andstate.gallery.folderId
)Cannot read property 'replace' of undefined
error on startup (history state doesn't have all required properties)backend.createEndpointFetcher()
rather than recreating on eachrender()
call inAssetAdmin
AssetAdmin
container layout regression (too much padding). May be "ensure HTML is good and give to Paul"reactRouter
boolean flag inLeftAndMain->getClientConfig()
)Things that don't block merge:
lib/Router
to avoid wrapping around page.js (ideally we don't need a custompage.show()
).back()
navigation on breadcrumbs (use newbrowserHistory
object) (docs)Related
Recommended Reading
The text was updated successfully, but these errors were encountered: