skip to Main Content

Suppose you have a Card component that takes content for the header, body and footer. One way to design it would be for consumers to use it like this:

<Card
  header="foo"
  body="bar"
  footer="baz"
/>

But I often prefer something like this:

<Card>
  <CardHeader>foo</CardHeader>
  <CardBody>bar</CardBody>
  <CardFooter>baz</CardFooter>
</Card>

To get the latter, I’m currently doing something like this:

const cardHeader = children.find(
  (child) => child && child.type && child.type.name === "CardHeader",
);

But I wonder if there is a more idiomatic way of doing it.

2

Answers


  1. From what I understand you cannot specify children, you can specify props.

    I would probably end up doing something like this:

    <Card
        header={<CardHeader>foo</CardHeader>}
        body={<CardBody>bar</CardBody>}
        footer={<CardFooter>baz</CardFooter>}
    />
    
    export default function Card({header, body, footer}) {
        return(
            <View>
                <header/>
                <body/>
                <footer/>
            </View>
        );
    }
    

    Edit: Thanks for the downvote I hope you find what you’re looking for.

    Login or Signup to reply.
  2. A general term you might look for is "slots", especially when used in reference to Vue’s slot feature or the Web Components <slot> definition in HTML. As of this writing, there is not an official idiomatic equivalent in React, but React RFC #223 ("Slots") proposes an extension in the future. That GitHub thread also describes some of the popular alternatives and the concerns in building this feature directly into React.

    For lack of an official "slot" solution, the most idiomatic built-in way to represent this in React is as you suggested:

    <Card
      header={<div>Header ...</div>}
      body={<div>Body ...</div>}
      footer={<div>Footer ...</div>}
    />
    

    You might also consult Sandro Roth’s article "Building Component Slots in React", which helpfully linked the RFC above. In particular, it describes the type safety benefits and concerns of the above pattern in comparison to "compound components"—a term which does not appear in official React docs but describes the pattern of nested tightly-coupled components that you depict in your question. This pattern does appear in libraries like react-bootstrap (e.g. hasChildOfType and its consumption) but the pattern is just that—a common design pattern that is not described or endorsed in the React docs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search