Having a render prop is slightly better but even this escape hatch isn't foolproof and you'll still end up needing things like onClickOutside.
Use a Render Prop
21–30 of 35 posts
Re: Use a Render Prop
#22Earlier quoted context omitted.
The term “higher order” generally indicates complexity and indirection. If you can solve something first order, then that is much more preferable to a higher order (function, logic, object) solution. Higher order functions fall into the same category (you can have them if you want, but you must understand what you are getting into in terms of complexity).
> The term “higher order” generally indicates complexity and indirection. As do all abstractions. > If you can solve something first order, then that is much more preferable to a higher order solution. a.k.a. "To abstract, or not to abstract?". It really depends, of course. But I know for certain I would not want to solve "mapping over an array" without the Array.prototype.map higher-order function.
Re: Use a Render Prop
#23My biggest issue with HOCs is the hard time you have when things are nested to high hell. A component like withThis(withThat(enrich(withState(withPropsOnChange(withPropsOnChange(withPropsOnChange(withPropsOnChange(....... when this component gives you an issue you begin to wonder what HOCs are really doing for you. Having a render prop is slightly better but even this escape hatch isn't foolproof and you'll still end…
@connect(mapStateToProps, mapDispatchToProps)
class Component extends React.Component { ... }
has a certain elegance to it.Re: Use a Render Prop
#24This technique is very useful, but passing the callback as a prop is an ugly way to do it. Much cleaner to pass the callback as children [0]. Then, the final example looks like: {({ x, y }) => ( The mouse position is ({x}, {y}) )} [0]: https://discuss.reactjs.org/t/children-as-a-function-render-...
This is how the technique was first popularised by Cheng Lou in react-motion. But it was generally found that using children made it really inaccessible to people unfamiliar with the pattern. I've literally had good developers not understand them until I switched an example from using children to using a render prop, at which point there's a big light bulb moment. So i'll be sticking with the render prop.
Re: Use a Render Prop
#25My biggest issue with HOCs is the hard time you have when things are nested to high hell. A component like withThis(withThat(enrich(withState(withPropsOnChange(withPropsOnChange(withPropsOnChange(withPropsOnChange(....... when this component gives you an issue you begin to wonder what HOCs are really doing for you. Having a render prop is slightly better but even this escape hatch isn't foolproof and you'll still end…
I think a lot of HOC libraries were designed assuming decorators would be standardized soon. The connect method from react-redux is definitely in that camp: @connect(mapStateToProps, mapDispatchToProps) class Component extends React.Component { ... } has a certain elegance to it.
However, I personally advise against using `connect()` as a decorator, for several reasons:
- It's still a Stage 2 proposal. Now, the Class Properties syntax isn't final either (currently Stage 3), which the React team (and I) highly recommend using. However, the Class Properties syntax seems to be much more stable, the behavior it's implementing is a lot simpler, and if by chance it happens to change in the future, it should be relatively easy to code-mod (and the React team has said they would release a code-mod if that happens). Meanwhile, the decorators spec has changed several times (including recently), and the Babel plugins have also had to change behavior and implementation over time.
- It obscures the real class definition. The standard advice for testing Redux-connected components is to export the "plain" class separately as a named export, and `export default connect()(MyComponent)`, then import and test the plain version. If you use @connect() as a decorator, the plain version isn't accessible, and testing becomes more difficult.
- Going along with that, I've seen many questions about why defaultProps and propTypes don't work right when @connect() is used, and it's because those get applied to the wrapper component, not the plain component, and thus things don't work the way you would want them to.
I see no advantages to using connect as a decorator. I encourage people to write their mapState functions separately anyway for clarity and testability (instead of inline as an argument to connect), so it's just a matter of moving the line with `connect` elsewhere in the file and changing the syntax slightly.
Re: Use a Render Prop
#26Earlier quoted context omitted.
I think a lot of HOC libraries were designed assuming decorators would be standardized soon. The connect method from react-redux is definitely in that camp: @connect(mapStateToProps, mapDispatchToProps) class Component extends React.Component { ... } has a certain elegance to it.
To some extent, it was - if you look at the earliest versions of Redux, `connect()` and its predecessor forms were indeed being used as a decorator. However, I personally advise against using `connect()` as a decorator, for several reasons: - It's still a Stage 2 proposal. Now, the Class Properties syntax isn't final either (currently Stage 3), which the React team (and I) highly recommend using. However, the Class P…
I've considered the first point, but hadn't thought about the second and third. I'm guessing the last point isn't a concern if you're using class properties for those?
Given all this, if you were redesigning the API today, would you now make connect take the component as the first parameter instead?
Re: Use a Render Prop
#27Earlier quoted context omitted.
To some extent, it was - if you look at the earliest versions of Redux, `connect()` and its predecessor forms were indeed being used as a decorator. However, I personally advise against using `connect()` as a decorator, for several reasons: - It's still a Stage 2 proposal. Now, the Class Properties syntax isn't final either (currently Stage 3), which the React team (and I) highly recommend using. However, the Class P…
I definitely wasn't recommending that usage, just illustrating what it might look like. I personally think it looks much cleaner, which I would call an advantage. I've considered the first point, but hadn't thought about the second and third. I'm guessing the last point isn't a concern if you're using class properties for those? Given all this, if you were redesigning the API today, would you now make connect take th…
const SpecificConnection = connect(mapState, mapDispatch);
const ConnectedFirst = SpecificConnection(FirstComponent);
const ConnectedSecond = SpecificConnection(SecondComponent);
Admittedly, I suspect that use case isn't popping up very often. Most of the time what I see is that a given component type is only connected once, and a given connection setup is only used with one component. I also don't remember seeing specific comments by Dan or Andrew saying that's why it's written this way - I'm inferring the intent from the API definition. Still, it's a potentially useful capability in the API, so no reason to throw it away.Re: Use a Render Prop
#28Earlier quoted context omitted.
This is how the technique was first popularised by Cheng Lou in react-motion. But it was generally found that using children made it really inaccessible to people unfamiliar with the pattern. I've literally had good developers not understand them until I switched an example from using children to using a render prop, at which point there's a big light bulb moment. So i'll be sticking with the render prop.
Maybe you could clarify it for your good developers by giving the example with children passed as a prop. Then they'll learn two things!
Re: Use a Render Prop
#29People seem to forget that components (stateless components, stateless functional components or whatever you want to call them) are just functions. One function calls another function, that's function composition. In plain JavaScript we do it all the time. But when React is involved people are suddenly all like: no you can't call that function directly, you have to name it 'Component' with a capital C and use like '…
Re: Use a Render Prop
#30My biggest issue with HOCs is the hard time you have when things are nested to high hell. A component like withThis(withThat(enrich(withState(withPropsOnChange(withPropsOnChange(withPropsOnChange(withPropsOnChange(....... when this component gives you an issue you begin to wonder what HOCs are really doing for you. Having a render prop is slightly better but even this escape hatch isn't foolproof and you'll still end…
The render prop pattern will have just as much nesting. Mixins or plain JavaScript class composition have major well-accepted problems. You could just write one big component with all that functionality, but the fact that it would ever be split into layers of HOCs implies that various functionality is being reused (and probably provided by third party libraries).