2

This is my reducer.js

const initialState = {
    counter: 0
}

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case 'increase':
            state = { ...state, counter: state.counter + 1 }
            break
        default:
            break
    }
    return state
}

export default reducer

This is my index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import reducer from './reducer'

const store = createStore(reducer, applyMiddleware(thunk))

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
document.getElementById('root'))

This is my code in React App.js

import React from 'react'
import { useDispatch, useSelector } from 'react-redux'

function App() {

    const dispatch = useDispatch()
    const counter = useSelector(state => state.counter)

    const increment = (dispatch) => {
        return function () {
            return Promise.resolve(dispatch({ type: 'increase' }))
        }
    }

    const myFunc = increment(dispatch)

    const onClickIncrease = async () => {
        console.log('Before dispatch:', counter)
        myFunc().then(() => {
            console.log('After dispatch:', counter) *** // Why this line prints the same value as Before dispatch ***
        })
    }

    return (
        <div>
            <button onClick={onClickIncrease}>
                +
            </button>
        </div>
    )
}

export default App

When I clicked the + button three times, I saw:
Before dispatch: 0
After dispatch: 0
Before dispatch: 1
After dispatch: 1
Before dispatch: 2
After dispatch: 2

I don't understand why the counter printed in Before and After are the same. Can anyone suggest what should I do if I want to see something like this:
Before dispatch: 0
After dispatch: 1
Before dispatch: 1
After dispatch: 2
Before dispatch: 2
After dispatch: 3

Dimisizz
  • 69
  • 9
  • Does the counter value update inside the store? Could you also post the reducer code? – Amruta Oct 25 '21 at 07:48
  • @Amruta Sure, I just edited my post. – Dimisizz Oct 25 '21 at 07:50
  • You've closed over the `counter` value in `onClickIncrease` callback scope, so it won't change there. This appears to be *some* trivial example, but what *real* issue are you trying to resolve? What is the actual use-case? If you just want a "before" & "after" then place the "after" in an `useEffect` with a dependency on `counter`. It will log when the state value updates. – Drew Reese Oct 25 '21 at 08:01
  • Think you could provide us a *running* codesandbox of your code that we can inspect and debug live? From what I can see it seems you are trying to return the updated state from a thunk back to the UI in the Promise chain. – Drew Reese Oct 25 '21 at 08:08
  • @DrewReese I just want to handle the updated state immediately after dispatching. Using useEffect with a dependency on counter as you suggested works for me. Thank you for your comments. – Dimisizz Oct 25 '21 at 08:13

1 Answers1

0

It's because Redux dispatched action call is asynchronous, so you could print something here, within your action directly:

case 'increase':
  state = { ...state, counter: state.counter + 1 }
  console.log('after')
  break
k-wasilewski
  • 3,943
  • 4
  • 12
  • 29