A
A
Andrey2017-03-15 00:06:38
React
Andrey, 2017-03-15 00:06:38

How to implement a method call in response to a state change in react-redux?

There are two components: an authorization form and a shopping cart. An unauthorized user may have an empty cart, while an authorized user may have goods there. Accordingly, after authorization, it would be good to request a basket using AJAX and update the state if its composition is different.
I use react-redux with "smart" and "stupid" components.
After successful authorization, I pass the result to action and change the user state to user.isAuthorized. Components that follow this property will be rerendered.
But I don’t need the cart to be re-rendered upon authorization, I first need to make an AJAX request, and then render the cart based on its results.
Controller components only have the connect() function with its argument functions that pass data to the view. Such components do not know how to somehow respond to state changes (I'm not mistaken in this, right?).
You can, of course, stupidly subscribe to user.isAuthorized changes, but there are two things that stop me:
1. It is not recommended to use it in guides
2. It will be called for every sneeze, essentially empty, in this case it is better to wrap it in an Observable and build that's all the interactions in the app.
Are there any traditional ways to solve this problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim, 2017-03-15
@f-end

Good afternoon.
Imagine your action creator (function), which on success returns a successful authorization, for example:

$.ajax(url...
  success(data) { dispatch({type: AUTH_SUCCESS, data }) })

Who's stopping you from doing so?
$.ajax(url...
  success(data) { 
    dispatch({type: AUTH_SUCCESS, data }) 
    loadUserCart(data.user_id) // <- еще один action creator
})

Is the point already clear? After successful authorization of the user, we immediately call the following action-creator:
function loadUserCart(id) {
  return (dispatch) => {
    
    dispatch({ type: CART_REQUEST }) // получается, это событие вызовется сразу после успешной авторизации, практически мгновенно

    
    $.ajax(urlForCartUpdate...
      success(data) { 
        dispatch({type: CART_SUCCESS, data })
    })  
  }
}

Next, you are in the shopping cart component, set up the preloader display, and voila! It turns out that for the user, without delay, as soon as he logged in, the preloader will spin at the basket. The user understands everything, he goes about his business. As soon as the "data arrived" - you hid the preloader and showed it the necessary data on the basket.
That is exactly what we did.
PS I don’t know if this is required, but just in case, I’ll point out that in order to make a preloader in the template, you need to create some field (flag) in the cart reducer, for example isLoading and set it to true when you receive an action with the CART_REQUEST type, and false for CART_SUCCESS. Thus, you can make a banal if in the render template and show either the preloader markup or the cart data markup.
=== second part ===
Even as they can, that's the point. You pass in mapStateToProps in the general case:
{
  ваше_название_поля: reduxStore.название_редьюсера
}

In a particular case, it might look like this:
function mapStateToProps(state) {
  return {
    rate: state.rate,
  }
}

Once you have "subscribed" to changes in state.rate (and this is most likely a reducer called rate in a particular case), your "attached" component will always receive new props when the reducer changes. Therefore, the render function will be called. Of course - you can connect at least how many "reducers" to one component.
Keep in mind that everything here is written to be understood in simple Russian, in fact, since you are using the Provider component at the very top level of your application, it throws the necessary props down. Your connect(Components) are able to respond to changes in the required props => react triggers a render because "new props have arrived".

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question