Aug 28, 2017 · 2 min read
While I appreciate the desire for clarity and craftsmanship in code, and I agree that passing callback functions down the tree isn’t ideal, I’m not sure that this approach is one I would want to use, for a few reasons:
- Simple delegators tend to misname the callbacks that the child component needs. For example, a
Taskcomponent should not have aonTaskCompletecallback but rather anonCompletecallback. This is a subtle distinction, but an important one for well-factored and conceptually pure components, and using a delegator pattern will tend to bias you away from noticing such things. - As user Chris Geirman noted in his comment, it’s not clear at the call-site what the child-component needs. Passing
delegate={this}is bundling some unknown set of methods fromthisand passing them to the child. I prefer a more explicit interface and generally find that explicit interfaces make code more legible and therefore maintainable. - A better state management approach avoids many of these problems. Flux separates the state from the components by use of “stores,” which store state and emit events when things change. A component that needs some state subscribes to those events and updates itself as needed. So you’re not passing callbacks down the tree. Redux (or more specifically
react-redux) providesmapStateToPropsandmapDispatchToPropsto interface between so-called container and presentational components. Maintaining the conceptual separation between these types of components solves many (though admittedly not necessarily all) of these “over-parenting” problems.
My criticisms aside, thanks for taking the time to write this up. I appreciate the quest for craftsmanship. Cheers!
