0

I have simple check, which I must do when user clicking the button:

<button 
    onClick={() => {
        this.props.validatingActions.validate(this.props.Email.Value);
        this.props.submittingActions.submitValidation(this.props.Email.IsValid);
}}>Submit</button>

At first, email in Redux store validates, then, some actions do, when email is valid or not.

The problem is, that this.props don't update after executing this.props.validatingActionsvalidate, they're only updates after leaving anonymous onClick function, therefore this.props.Email.IsValid has old value.

How can I properly update props in such situations?

Yurii N.
  • 5,455
  • 12
  • 42
  • 66
  • Why aren't you calling validate when the user changes the email field? This can be a debounced function if you're concerned about performance. – Mike Lawson Feb 22 '17 at 13:38
  • Because this is simplified example, I have really many fields like this. What do you mean by debounced? – Yurii N. Feb 22 '17 at 13:42
  • Debouncing a function is a way to ensure it's not called multiple times - that is to say clicking a button 5 times won't result in 5 submissions. Can you post your action creators and reducers? – Mike Lawson Feb 22 '17 at 13:59
  • Now, i don't have them, but I understand what is it. – Yurii N. Feb 22 '17 at 14:29
  • The problem exists because you're dispatching two actions at the same time, which is causing a race condition in your current store state. You'll likely need to use some middleware like `thunk` or `redux-saga` in order to make this work the way you'd like it to. – Mike Lawson Feb 22 '17 at 14:33
  • I'm currently using `thunk`, firstly I dispatch `request` type then `success` or `error`. – Yurii N. Feb 22 '17 at 15:10

3 Answers3

2

Please note that you shouldn't (and in most cases can't) change a component's own props. Please check this SO answer for more details.

Answer update

Also please be aware that React setState is asynchronous so state changes are not made immediately after calling setState. And as a result props which are based on state also aren't updated immediately after dispatching an action.

When prop is updated components is re-rendered and if you need changed prop value immediately I assume it's not needed in component render function but somewhere else to decide if perform another action or not. If so it should be handled in actions: you can use redux-thunk to dispatch asynchronous or conditional actions.

Community
  • 1
  • 1
Bartek Fryzowicz
  • 6,464
  • 18
  • 27
  • I don't change them, my component props managed by `connect` function provided by `react-redux` library and 'mapStateToProps' function, whhich is responsible for mapping redux store to componeent props. – Yurii N. Feb 22 '17 at 13:33
  • In that case, you should dispatch an action to call a state reducer to update the values you're looking to change. You can do those by using `mapDispatchtoProps` within `connect` as described http://stackoverflow.com/questions/39419237/what-is-mapdispatchtoprops – Mike Lawson Feb 22 '17 at 13:34
  • This is what I do, that's the main problem, that we can't have new props values inside function, without leaving it. – Yurii N. Feb 22 '17 at 13:41
  • It's expected react behaviour – Bartek Fryzowicz Feb 22 '17 at 13:45
  • @BartekFryzowicz ok, so, what should I do then, if I my requirements break that behaviour? – Yurii N. Feb 22 '17 at 13:58
  • 1
    Well, when props are updated components is re-rendered and if you need changed prop value immidiately I assume it's not needed in component render function but somewehere else to decide if perform some action or not. If so IMO it should be handled in actions: you can use `redux-thunk` to perform asynchronous or conditional actions. But it's really hard to provide detailed solution seeing only small piece of your code – Bartek Fryzowicz Feb 22 '17 at 14:35
0

Try to use Redux-Form http://redux-form.com/6.5.0/examples/syncValidation/, when you want to work with forms

UserGraund
  • 310
  • 2
  • 5
  • Seems good, but I can't switch to this library in current situation for most reasons, so, how about solving current problem? – Yurii N. Feb 22 '17 at 13:28
  • This is bad advice for two reasons. Redux-Form is complex and powerful, and not needed for most situations, and it's definitely not answering the current question. – markerikson Feb 22 '17 at 17:10
0

Changing props isn't the way to solve it. Where is your logic for validating and submiting? Directly in the reducer? Either do both things on the same action, or use a side effects library to do one after the other. In any case, judging by the names of the actions, I don't see why you would use redux actions for that. Validating an input doesn't sound like a state change to me. You should validate it with a simple function and depending if it's ok or not, act (with an action) accordingly.

jorbuedo
  • 2,041
  • 1
  • 8
  • 20