2

I have a question about the following example code, which seems to have something to do with redux data flow inside.

// action.js
export function doSomething() {
    return {
       type : 'FOO',
       data : 'BAR'
    };
}

// reducer.js
...
case types.FOO :
    return update(state, { mystatus : { $set : action.data } });
...

// container.js

class MyTestClass {

    ...

    handleButtonClick() {
        this.props.doSomething(); // doSomething is just simple, synchronous action creator. In this function, state.foo 
        console.log(this.props.status);  // expected output should be 'BAR' but, actual output is 'undefined'
    }

    ...
}

const mapStateToProps = (state => {
    return {
        status : state.mystatus
    };
};
const mapDispatchToProps = (dispatch) => {
    return {
        doSomething : () => {
            return dispatch(doSomthing());
        }
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(MyTestClass);

Now, this is my question.

If you see the code 'this.props.doSomething(); console.log(this.props.status);' in handleButtonClick method, the output of this code is supposed to be 'BAR'. However, I got 'undefined'.

this.props.doSomething();
console.log(this.props.status); // output is 'undefined'

And, If I change that part like following, I could get what I expected.

this.props.doSomething();
setTimeout(() => { console.log(this.props.status); }, 0); // now output is 'BAR'!!

I thought that "calling this.props.doSomething() => creating action => dispatching => mapping the changed state to the property by redux" was a series of synchronous control flow, but it does not seem to be.

There seems to be an asynchronous control flow in the process of being dispatched.

Is it a bad idea to call a function mapped to a property and use that function's output immediately when using react-redux? Could you explain how react-redux handle this inside?

Thnak you.

Maxim Kuzmin
  • 2,574
  • 19
  • 24
novice
  • 23
  • 4
  • According to this post, https://stackoverflow.com/questions/43276291/is-store-dispatch-in-redux-synchronous-or-asynchronous, dispatch is synchronous. Where is your store creation code? We have to look at your reducer definition. Are you sure `state.mystatus` points to the correct place? – nbkhope Aug 25 '17 at 00:06
  • To answer your question, it is not a bad idea. I do that very often. The only difference is I use redux-thunk to define asynchronous action creators. That way, I can do `this.props.doSomething().then(() => { doSomethingElse(); })` – nbkhope Aug 25 '17 at 00:08
  • @nbkhope yes. I also use in that way(with usually promise). I just wanted to do some experiment to figure out how redux works internally. The store creation part should be fine. That's why console.log(this.props.status); code doesn't work, but setTimeout(...) code still works. – novice Aug 25 '17 at 00:49

1 Answers1

0

According to this, React Redux uses setState under the hood.

If you use bindings like React Redux, this is the point at which component.setState(newState) is called.

According to this, setState() is asynchronous and batched for performance gains.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

Also,

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

So if you want to react to state changing in terms of view, you should use renderhook for it. If you want to react to dispatching some action in terms of actions (logging, initiating another action), you should create middleware (generic cases) or use redux-saga/redux-thunk (receiving actual particular event and do something) depending on your task type.

Maxim Kuzmin
  • 2,574
  • 19
  • 24
  • Thnak you! Your answer was really helpful! – novice Aug 25 '17 at 00:52
  • @novice please consider accepting answer if it is helpful – Maxim Kuzmin Aug 25 '17 at 01:24
  • So, now I understood that I need to make sure waiting after the rendering is triggered when reading the changed state after some action. Also, I just found that the marker to accept your answer.. This is bad ux though.. – novice Aug 25 '17 at 01:24