Home > Back-end >  Attaching React functional components in compound pattern?
Attaching React functional components in compound pattern?

Time:02-21

I am building a React component using the compound pattern as follows:

import React from "react";

function Card({ children }) {
  return <div>{children}</div>;
}

function Heading({ children }) {
  return <h2>{children}</h2>;
}

export Heading;
export default Card;

I'm not sure why I cannot use the export as above. However when I do

Card.Heading = Heading;
export default Card;

I'm now able to consume as follows:

<Card>
  <Card.Heading>hello</Card.Heading>
</Card>

I am trying to find out why Card.Heading = Heading is working as expected. Is it valid to attach react components using dot[.] notation like how I did?

CodePudding user response:

I would assume this is a valid pattern.

Since React components are functions and functions are first-class objects, it's valid to assign properties like you have done. See the excerpt here.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

As far as importing Card if you wanted to use Card in another file you'd need to do the following.

import Card from './Card' since it's the default export.

Alternatively you could change the export to looks something like this.

export default {
 Heading,
 Card
}

CodePudding user response:

Your first attempt is not working, because you didn't attach Card to Heading before exporting. An export don't attach them, in fact you would import them like so (I assume we are in a file called Components.js):

import Card {Heading} from "Components";

That has been said, because a component should be independent (it is the philosophy), you shouldn't be (even if it is valid, since functions are objects in JavaScript) attaching them like this for readability :

Card.Heading = Heading;

If you wanna consume different components as one with proprieties, you would do something like this :

function Card({ children }) {
  return <div>{children}</div>;
}

function Heading({ children }) {
  return <h2>{children}</h2>;
}

export Heading;
export Card;

Then where you need those components, you do this:

import * as Component from "Components"
function App({ children }) {
  return(
  <Component.Card>
      <Component.Header />
      {children}
  
  </Component.Card>;)
}

export default App;

CodePudding user response:

you can use arrow function, this should fix your issue

import React from "react";

function Card({ children }) {
  return <div>{children}</div>;
}

export const Heading = ({ children }) => {
  return <h2>{children}</h2>;
}

export default Card;
When importing from other file :

import Card, { Heading } from 'file emplacement';
  • Related