I have a React app, using Redux & Redux Sagas.
Currently I have a fairly standard search page as in :
User enters value via form input, magic happens behind the scenes, an api is consumed and my redux store is populated with the results.
These results are then surfaced via the view layer.
Using React Router 4, if I then navigate away to another page, on returning to the search page, my previous results are still shown. I guess this is expected as my redux state still contains this data.
My Questions is should this state be cleared on navigate away? I am very new to Redux / React / React Router and am trying to understand if I have implemented this correctly or in fact unless I instruct the store to clear that state, it should persist.
tl:dr
Should a redux store be cleared if I navigate away from the page or is it ok to leave that data on the view?
Using React Router 4, if I then navigate away to another page, on
returning to the search page, my previous results are still shown
In React & Redux epoch you web application is SPA, and tools like isomorphic react-router-dom helps with this task, including seamless SSR support for URL router.
Of course, you can use react-router-redux instead, and in this case navigation to different pages will appear as actions, so them can be catched in saga, and then load new initialstate for redux store.
Library and example can be found here: https://github.com/jfairbank/redux-saga-router
Related
I have read the official Redux documentation regarding React Router and investigated react-router-redux, redux-router and redux-little-router. I also agree with the rational for redux-little-router: React Router has strong architecture consequences on a React app, and they somehow conflict with Redux.
My feeling about routing is that it has too much importance in the React+Redux ecosystem, whereas it should be treated as a second class citizen. When designing a single page app, we often don't need URLs at all. We still support them to preserve the Web experience (SEO, bookmarking...), but we certainly don't want them to drive the app structure.
What I am thinking of:
External navigation: a route-to-state mapping, with the classic reduced action mechanism. In other words, navigation triggers an action that is dispatched and processed by a custom reducer (with just some help for route mapping and parsing). Once the state is updated, this is React as usual. In particular, there is no mapping between routes and React components, unlike what React Router's Route does and a bit like redux-little-router does.
In app navigation: the current URL is derived from the state, a bit like the view. A kind of renderURL function a Redux middleware is aware of. If a state update generates no change in the URL, well, nothing happens. But if the URL is now different, the middleware reflects the change by pushing it to the history.
With this approach, there is no more Link component. There are only regular Redux actions and a middleware to take care of the navigation as a side effect. Actually, this solution does for navigation what React does for the DOM: a (super-straightforward) URL reconciliation, with the state as the single source of truth.
To illustrate this, consider the Redux Todo list example:
When visiting /SHOW_ALL, an action containing the URL is dispatched. A regular, navigation-dedicated reducer sets visibilityFilter to VisibilityFilters.SHOW_ALL in the state, possibly with some route mapping/parsing helpers. As an alternative, the navigation action could be turned into a SET_VISIBILITY_FILTER action, which is then dispatched and reduced as usual.
A fancy renderURL function is registered at store creation as part of a middleware. It returns "/" + state.visibilityFilter. Again, some route management helpers would be welcome for real life apps.
Now there is no change in the original Todo app. We only add some new code to support a new feature.
The problem is: I can't find anything that support this vision. No article, no react-redux-something package. As a React beginner, either I am a genius or there is something I don't get. Since the later is the most likely (to my uttermost dismay), I would appreciate:
Feedback regarding the "Redux-driven React routing", or whatever it should be named. How is it flawed?
Hints about how I should consider Redux and routing, like relevant articles.
I got a question while working with React-redux/redux-form.
I build SPA using React-Router.
React-router uses redux as you know.
What I want to know is the render-flow when you change redux-form-field.
1. user inputs text in redux form field
2. redux form updates redux store
3. Then, all components connected with store are re-rendered.
(It means that all page is refreshed in my case, because I use react-router)
React uses virtual-dom, so twinkles can't be notified.
I'm sorry that I can't express my thinking due to lack of English.
I look forward to hearing your opinions
I am converting a jsp multi-page app(mpa) into a React single-page app (spa). In the mpa, the back button worked and the form retained its state.
In my new React app, the back button works but the form does not retain its state.
Question: is there a trick to make my form retain its state after "backing" to it (in an spa).
Here are the two solutions I came up with:
Encode the entire form state into the url. Then update the browser history with an updated url every time the form changes. But, this seems like a huge pain in the butt.
Modify the structure of my app such that the form in question (a React Component) stays mounted (and just use the css visibility or display property to show and hide). But, in a large app, leaving every page mounted in the DOM seems like it might lead to performance problems.
By the way, I am using popstate and the browser history api to achieve SPA behavior (i.e. i have rolled my own router) as described here.
Hopefully someone can propose a solution that is better than my two solutions. Thanks.
I ended up using something similar to Wylie Кулик's answer with a few changes:
I didn't want to switch to Redux for just this one use-case. So I used the component state of my top-level component (i.e. a component higher up the tree).
I cached the form's state on the form component's componentWillUnmount and restored the cached state on componentDidMount.
I passed the cached state as a prop from the higher component to the child component.
It ended up being a very small amount of code and is working like a charm so far.
Use Redux to have a state store which transcends any particular component. Then in your component, as part of the form submission process, dispatch an action with payload of all of the form data. This should be cached on state and then when the component is remounted by your navigation structure, it should have access to this cache via Reduxsconnectfunctions mapStateToProps method. You can repopulate your form from that.
It's not clear from your question whether or not you are submitting the form in the traditional old way. I would use e.preventDefault in the handler instead, and have all the form data on the component's state, this can be sent to Redux's state store as described above, and Ajaxed off with superagent or similar. At the same time it can be cached.
Redux: http://redux.js.org
I'm working a React Native app using ExNavigator and I want to use Redux. I want a basic login flow, by which I mean:
User clicks "Log in" with correct info
Redux does a usual async flow through redux-thunk or something
When the user is logged in/request was successful, move to Profile route
I've done Redux login in the web, but I am sort of confused as to how to move ExNavigator to the Profile route when the login works because the Navigator object seems to be contained completely in the components and not Redux.
Any pointers?
A pattern I use often is detecting state changes in my component's componentWillReceiveProps, and triggering the navigation transition from there.
Let's say your state contains a property isLoggedIn, which you set to true when the login is successful. The property is also passed as a prop to your component. You can then:
componenWillReceiveProps({isLoggedIn}) {
if (isLoggedIn && !this.props.isLoggedIn) {
this.props.navigator.push(nextRoute());
}
}
This might not be the most elegant way of solving the problem, but it works. The React Native Navigator, and consequently ExNavigator built on top of it, does not lend it self easily to the Redux architecture.
React Native team is working on a new navigation API, currently known as NavigationExperimental, which ships with latest versions of RN. It works nicely with Redux (example), but as its name indicate, it's still very much experimental.
guys. When I go through the documentation of redux-router, I just cannot understand why do we need it?
Here is what the documentation is trying to explain:
React Router is a fantastic routing library, but one downside is that
it abstracts away a very crucial piece of application state — the
current route! This abstraction is super useful for route matching and
rendering, but the API for interacting with the router to 1) trigger
transitions and 2) react to state changes within the component
lifecycle leaves something to be desired.
It turns out we already solved these problems with Flux (and Redux):
We use action creators to trigger state changes, and we use
higher-order components to subscribe to state changes.
This library allows you to keep your router state inside your Redux
store. So getting the current pathname, query, and params is as easy
as selecting any other part of your application state.
As far as I can understand, it is trying to say redux router can keep router state inside redux store so that we can get route info more conveniently.
But within react-router, I can also easily do it.
Like path="messages/:id", I can use this.props.params.id to get the params.
Can someone explain in what scenario redux-router bring its benefit?
Redux (and in general, the flux pattern) is all about having the entire application state stored in one central place. This has the benefit of easier debugging and makes it easier to implement certain features.
If you've ever used the redux-devtools in a react app with react-router, you'll notice that its only of limited use, because you can't replay the entire lifecycle of the application. When the user changes routes, that's not recorded in the redux store. Redux Router keeps the route state in the store.
You could use this for debugging, you could serialise the entire store history and log it elsewhere to replay user sessions. You could hook into it to implement full undo, or log analytics events.
redux-simple-router is a library which could help you understand how to use react router in a redux application.
It is a very simple library stores the URL in redux state and keeps it in sync with any react-router changes.
redux-simple-router compared to redux-router is:
Much smaller and simpler. You don't need to learn another library on top of everything else.
Encourages direct access of react-router APIs. Need server-side rendering, or something else advanced? Just read react-router's docs.
Only stores the current URL and state, whereas redux-router stores the entire location object from react-router.
Follow one of the these 2 examples to get up and running:
redux-simple-router-example
redux-frontend-boilerplate