1. 4
  1.  

  2. 4

    It’s a cute technique, though I don’t see how it solves the issue of concerns.The way that Card is implemented, it still conflates those concerns, because it needs to know those properties. The fact that you pack them in children instead of props doesn’t really change that. If you truly want to decouple them, you blindly render {children}.

    edit: You could also just conventionally model your props as {config: Record, content: Record}. I guess my point is, we’re not really, truly separating concerns here. We’re just making it more clear what is config and what is content.

    1. 1

      We’re just making it more clear what is config and what is content.

      I think this is what the author means by “separating concerns”.

      1. 1

        My point is, clarifying the difference doesn’t separate the concerns. I’m not saying its not a useful thing to do, just that it seems to be a misunderstanding of what “separation of concerns” is. The component still hard-couples its contents to its interface. If that is done via children or other props is irrelevant.

    2. 2

      Another, albeit, more ‘verbose’ approach is

      https://react-bootstrap.github.io/components/cards/

      I like it because, it let’s me define additional properties on title/etc (if needed).

      Perhaps, as a personal preference, I prefer to see a clear separation between ‘visual’ elements and ‘attributes of visualization’ of a particular element.

      With that view, attributes – should be passed as properties in JSX. But the visual elements themselves should reflect the DOM paradigm (eg JSX) in the case of react, and should be passed as full fledged children of React.Node type

      So ‘text’ is a visual element, therefore should not be passed as property or children-object.

      1. 1

        This is not really separating your concerns. Furthermore, has the issue of now having a rigid structure for the children “prop” that is not really known to the outside world, and against how it is normally used which can be confusing (and for most, would result in not really even checking the format for it, unlike a prop). Why not do it like;

        <Card
          size="large"
          content={{
            title: 'My lovely title',
          }}
        />
        
        1. 2

          You can validate the children prop just as any other prop, but to your point I think linters won’t complain if you fail to provide a propTypes entry for it.

          Otherwise there’s already precedent for this kind of thing with the children as function pattern, so I don’t think having children be a plain object is too much of a stretch:

          <Card>{ 
            value => <strong>{value}</strong>
          }</Card>
          
          1. 1

            Good point, although both of the patterns I find a bit… tacky. That could be just personal preference though; I try to ensure children are always of type React.ReactNode, to make components a bit more predictable in terms of their APIs.

            What would be the benefit of either case over using a prop to supply the function / config in your opinion?

            1. 1

              In general, the render prop pattern is useful in a variety of cases; the choice between “children” or another prop name is mostly cosmetic, I think. For components with a single “slot” for children, I prefer to use the children prop for the purpose. For multiple slots, I don’t think I’d choose to separate them from the other props like the author suggests. But at the end of the day, at least for my kind of setup (Sublime Text), I still have to look up the component’s API somewhere…. maybe some IDE feature might make one choice better than the other?