Search code examples
javascriptreactjsreduxreact-redux

How to pass data to component?


Warning: you might have spelling stroke

Hey! I've got a very simple question (maybe): how should I pass data to my component? Now I can see only 2 solution: props (from App to my component) and redux (mapStateToProps, mapDispatchToProps) (let's skip ContextAPI for now)


Case #1 (props (from app to my component))

For example, I've got a goods list on my site. Then my list have to recieve data to render it. I should pass it through App, Main, SomeWrapper, SomeOtherWrapper, GoodsList (for example), do not make a mistake and only after that render all goods. Now, let's imagine that I need to add onCLick to GoodsItem => I need to pass onGoodsItemClick through all components, fix all tests (because PropTypes will warn) and PropTypes. It's a little complicated, routine and not very technological, isn't it?

Case 2 (redux (pass through only requirement props with mapStateToProps, mapDispatchToProps))

Okey, let's have a look on second case: sorting component. I've written connect functions for my component. They are looking like these:

const mapStateToProps = (state, ownProps) => ({
  ...ownProps,
  sortType: state.sortType,
  allOffers: state.allOffers // allOffers imports only for mapDispatchToProps
});

const mapDispatchToProps = (dispatch) => ({
  onSortChange: (allOffers, sortType) => {
    dispatch(ActionCreator.changeSortType(sortType));
    dispatch(ActionCreator.sortOffers(allOffers, sortType)); // allOffers is using only here
  }
});

Here I have to receive allOffers only to give it for mapDispatchToProps for sort function (maybe mistake is here. As I know, ActionCreator has no access to store and have to work only with args). Why should I receive data, which will not even render on the page?

What do React developers do in such a situation? Use only one method? Use both in different cases? Combine this two methods with revisions? Use third method?


Solution

  • I guess we agree that your "Case #1" example is the wrong approach.

    Your redux example ("Case 2") suggests that you are passing sortType and allOffers to this component solely to have some place to call a useEffect or something, and the component doesn't care at all about these properties.

    1. So why using this component at all for calling onSortChange(), why not handle it in the parent component ?

      1. Instead of passing sortType and allOffers down, you can pass onSortChange as a callback.
      2. If onSortChange is called inside a useEffect, then you probably can move the useEffect itself up into the parent component, maybe split it into two useEffects, if it does more that just calling onSortChange.
    2. sortType and allOffers are properties of the redux state, so probably you don't need to pass them at all, because they are available in the reducer. In case you have different reducers and none of them has both states together, you might consider

      1. redesign the state / reducers
      2. pass only one of the properties to the reducer, and use the other one from the state directly inside the reducer

    Note: I always found "clean" solutions for problems like this until now, but I'm still not sure if it definitively always can be done, or if this is answerable in general. If my solutions are not possible for your use case, feel free to add a comment to explain why not (or update your question accordingly).