user3378165
user3378165

Reputation: 6916

Pass down a component with props

My main Home component renders different content based on conditions.

I need for the <SearchPanel /> component to pass the user as a prop but I also need the user data in the Layout component.

This code works fine but I don't think it is correct to send the user twice as props. How can I change that?

export default class Home extends React.Component {
  render() {
    return (
      <AuthConsumer>
        {({ user }) => {
          if (!user) {
            return <ErrorPage />;
          }
          if (!user.roles.includes('Admin') && !user.roles.includes('Observer')) {
            return <Layout pageContent={<NoAccessPanel />} user={user} />;
          }
          return <Layout pageContent={<SearchPanel user={user}/>} user={user} />; //not sure about this
        }}
      </AuthConsumer>
    );
  }
}

Layout component:

export default function Layout({ pageContent, user }) {
  return (
    <div css={bodyWrap}>
      <Header appName="Test" user={user} />
      {pageContent}
      <Footer />
    </div>
  );
}

Upvotes: 0

Views: 79

Answers (2)

Estus Flask
Estus Flask

Reputation: 223074

If there are many components that are supposed to receive user context, they should be context consumers. This is a use case for higher-order component:

const withUser = Comp => props => (
  <AuthConsumer>
    {({ user }) => <Comp user={user} ...props/>}
  </AuthConsumer>
);

Home, Header and SearchPanel are supposed to be augmented with withUser(...) and receive user prop this way, e.g.:

header-module.js

export class Header ... 

export default withUser(Header);

While Layout doesn't use user context itself and doesn't need to receive it.

Upvotes: 1

Fraction
Fraction

Reputation: 12993

Why you don't do the test in the Layout component ? :

Home Component:

export default class Home extends React.Component {
  render() {
    return (
      <AuthConsumer>
        {({ user }) => {
          if (!user) {
            return <ErrorPage />;
          }
          return <Layout user={user} />
        }}
      </AuthConsumer>
    );
  }
}

Layout Component:

export default function Layout({ user }) {
  return (
    <div css={bodyWrap}>
      <Header appName="Test" user={user} />
      {
        (!user.roles.includes('Admin') && !user.roles.includes('Observer'))
        ? <NoAccessPanel />
        : <SearchPanel user={user}/>
      }
      <Footer />
    </div>
  );
}

Upvotes: 0

Related Questions