I have encountered what I think might be a bug but could be my understanding.
Basically an import
of an async
action
returns undefined inside a Redux
container, but I know the import is fine (file exists, it's the right case etc etc).
On closer inspection, the issue seems to have started when I migrated to the shorthand object notation in my container, here's an example:
thunks.js
import { anAsyncFunc } from './anotherFile'
export const aThunk = () => async (dispatch, getState) => {
await dispatch(anAsyncFunc)
return dispatch(someOtherAsyncFunc)
}
containerThatDoesntWork.js
import { aThunk } from './thunks.js'
import MyComponent from './MyComponent'
console.log(aThunk) // undefined
const mapDispatchToProps = {
aThunk
}
containerThatDoesWork.js
import { aThunk } from './thunks.js'
import MyComponent from './MyComponent'
console.log(aThunk) // undefined
const mapDispatchToProps = dispatch => ({
aThunk: () => {
console.log(aThunk) // return async function (dispatch, getState) { ... }
return dispatch(aThunk())
}
})
In both instances if I console.log(aThunk)
in the container
I get undefined which I presume is something to do with the module resolution of async
functions?
However in the second example where the import is wrapped explicitly in a function, the component is happy and in the shorthand notation it is not (PropTypes validation fails).
Does anyone know a way round this? or is it a limitation to mapDispatchToProps
in object shorthand notation?
const mapDispatchToProps = {
aThunk
}
and
const mapDispatchToProps = dispatch => ({
aThunk: () => dispatch(aThunk())
})
are supposed to behave the same way. In case mapDispatchToProps
is an object, properties are transformed to () => dispatch(action)
automatically. Both should result in aThunk
prop that returns the result of aThunk()(dispatch)
, i.e. a promise.
Here is a demo.
The only reason why named import can be undefined in module scope but exist in function scope is that there is circular dependency that was resolved at the time when a dependency was lazily accessed. Wrapping a dependency with a function like this was done with dispatch => ...
is a known workaround around circular dependencies that is luckily supported by mapDispatchToProps
, but it's preferable to not have them in the first place, especially if this isn't by design.