Hacker News new | ask | show | jobs
by flowerlad 1778 days ago
> you had to wrap your components into x number of HOCs to inject the props your component needed, risking props collision, making it really hard to debug...

What kind of application are you developing? Do you have complex UI? Or just lots and lots of pages where you reuse components a lot?

1 comments

The kind of app that has 60k LOC, dozen of pages, makes 15 fetches per page (e.g. a report with 5 charts and 3 series per chart), reuse data between pages to avoid remaking the same fetches, have 1 or 2 forms synchronized between every page (like dates and selects filters), save the filters into the URL query params to be able to share the report and restore it when you open/refresh the app, and so on.

You end up with code like this at the bottom of your files

    myCustomHOC1(
      myCustomHOC2(
        withRouter(
          reduxForm({ form: 'filters', initialValues, destroyOnUnmount: false })(
            connect(mapStateToProps, mapActionsToProps)(MyComponent)
          )
        )
      )
    )
Although it's probably not that common anymore (as OC said, practices changed), it was a common pattern a few years ago.

In the new project I started last week, I'm using only hooks/context and a few libraries like react-router (useHistory, useParams), react-query (useQuery, useMutation), react-hooks-form (useForm)… and it has been a breath of fresh air. react-query is definitely another "big shift", it completely changed the way I used to think about fetching data and centralize it. It's very good, I highly recommend to try it.

Your example would be considerably simpler if you had separation of concerns [1]. You have routing, data fetching, redux, visual components, all in that small snippet. Sadly React devs seem to do this all the time... its like they have never heard of MVC.

[1] https://medium.com/@dan_abramov/smart-and-dumb-components-7c...

I suggest searching what each of those HOCs is doing. This code is not dealing with routing, fetching, managing state or rendering. It is merely "gluing" those things together. Doing that can be considered a "single concern".

Over-splitting things only makes them worse to read and understand, even though each sub-component is prettier to look at.

Also notice there's a disclaimer on your linked article here the author retracts the recommendation.

> It is merely "gluing" those things together.

That's pretty bad if you need "glue".

> Over-splitting things only makes them worse to read and understand, even though each sub-component is prettier to look at.

React is a UI technology, and only your view layer should know about the React stack. The model layer should be UI-technology agnostic (includes avoiding Redux etc.) and so should most of the controller layer. If something better than React comes along (and it will) only the view layer should need to be rewritten.

Once again, I suggest that you search what each of those HOCs is doing.

These functions are not part of what would be a controller or model layer in MVC. This code is not dealing with routing, fetching, managing state or rendering. They are merely gluing complex data coming from these other parts of the system into what is the view layer here. The logical separation still exists!

Sure OP could reimplement all of them by hand, but ultimately it doesn't matter: the code is still properly separated in the way you're mentioning. Libraries like those are free to have functions operating in multiple concerns, as long as the logical separation still exists, which it does.

Once again: UI should not be aware that routing is happening. It makes the UI less reusable.
The snippet illustrates exactly the concepts described in the article you linked.

And you are talking about MVC but that's kinda what is going on here: a bunch of smart components are injecting data ("model") and methods ("controller") into a dumb component ("view"), which displays them and calls them when some events are triggered (e.g. mount, change, clicks, submit, etc).