0

I am looking to hook up React Redux to my component in typescript. I am using these docs as a template.

I have the following type defining the state I have in the Redux store (there is only one):

export interface rootState {
  favourites: ImageThumbnail[]
}
 

My component:

...

interface StateProps {
  favourites: NasaImageThumbnail[]
}

interface DispatchProps {
  addFavourite: () => void
  removeFavourite: () => void
}

interface OwnProps {
  ...
}

const mapState = (state: rootState) => ({
  favourites: state.favourites
})

const mapDispatch = {
  addFavourite: () => ({ type: 'ADD_FAVOURITE' }),
  removeFavourite: () => ({ type: 'REMOVE_FAVOURITE' })
}

type combinedProps = StateProps & DispatchProps & OwnProps

//Component body

export default connect<StateProps, DispatchProps, OwnProps>(
  mapState,
  mapDispatch
)(Component)

mapState within the connect function is producing the following error:

No overload matches this call. The last overload gave the following error. Argument of type '(state: rootState) => { favourites: ImageThumbnail[]; }' is not assignable to parameter of type 'MapStateToPropsParam<StateProps, OwnProps, DefaultRootState>'. Type '(state: rootState) => { favourites: ImageThumbnail[]; }' is not assignable to type 'MapStateToPropsFactory<StateProps, OwnProps, DefaultRootState>'.

1 Answer 1

2

Don't pass all those generic args to connect. They should generally be inferred.

In fact, per that page, we specifically recommend using the ConnectedProps<T> technique to infer the type of props passed from connect to your component.

You should also note that:

Sign up to request clarification or add additional context in comments.

7 Comments

Curios about the recommendation to prefer redux hooks. I'm new to React-Redux but am developing a large project using redux-toolkit. My biggest concern with hooks is that the component has knowledge about the root state shape and I can't reuse it or refactor my code without changing the selector in every component. Currently, I am connecting my components in my slice file after I create the state slice so if I do change the state all of my required connection updates are in one place. My hooks concerns are reusability and coupling of components to state shape. Maybe my concern is misguided?
The question is understandable, but not a serious concern. The "selector state shape" question applies regardless of whether you're using connect + mapState or useSelector, because both of them receive the root Redux state object as their only argument. No difference there. If you are strongly concerned with avoiding rewriting anonymous selectors in components, create a reusable selector that can be called in many components instead so that you only have to edit the reducer and that selector if the state shape ever changes.
For more details on this, see my posts Using Reselect Selectors for Encapsulation and Performance, Thoughts on React Hooks, Redux, and Separation of Concerns, and ReactBoston 2019: Hooks, HOCs, and Tradeoffs. This is also a good argument for using TypeScript as well.
Oh, and I would avoid defining component connections in the slice file. Definitely not an idiomatic approach, and tbh I can't remember ever seeing anyone else ever do that.
The connection in the slice file was something I did because I didn't want to import other parts of my project into my component (except for interfaces which I keep in another file per feature). My reasoning was that if I'm defining my state slice in one file, the connected components are associated with the state so why should I do the connection in the component file? Seeing the connect at the bottom of the component file never felt great to me even though I did see examples of that. I'm a complete noob to redux-react and thanks for Redux-Toolkit.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.