Colin Sygiel
Colin Sygiel

Reputation: 947

How do you dynamically render a component based on incoming props, in React?

I have a component that I want to render that will render differently based on the incoming props:

const Label = ({ data, attribute, style, link }) => (
  <Link to={link} style={style}>{data ? `${data[attribute]}` : ''}</Link>
);

style and link props are optional so I want to render component differently based on whether they exist or not - the only way I can think of doing it is like this, but the jsx is wrong. What is the best practice in React? Thanks.

const Label = ({ data, attribute, style, link }) => (
  if(link && style) { 
    <Link to={link} style={style}>{data ? `${data[attribute]}` : ''}</Link> 
  } else if (link) {
    <Link to={link}>{data ? `${data[attribute]}` : ''}</Link>
  }
  //...
);

Upvotes: 1

Views: 428

Answers (2)

Julio Betta
Julio Betta

Reputation: 2295

You can create a prop to be used specifically for the Link component and defining the propTypes accordingly. In the example below, the prop linkProps is spread in the Link component.

// a simulation, just to make my point...
const Link = props => (<div {...props} />);


const Label = ({ data, attribute, linkProps = {}}) => (
  <Link {...linkProps}>
    {data ? `${data[attribute]}` : ''}
  </Link>
);

Label.propTypes = {
  data: React.PropTypes.object.isRequired,
  attribute: React.PropTypes.string.isRequired,
  linkProps: React.PropTypes.shape({
    style: React.PropTypes.object,
    to: React.PropTypes.string
  })
};


class Main extends React.Component {
  render() {
    const data = { label: 'Hello!' };
    const linkProps = {
      style: { fontWeight: 'bold' }
    };

    return (
      <div>
        <Label data={data} attribute='label' />
        <Label data={data} attribute='label' linkProps={linkProps}/>
      </div>
    )
  }
}

ReactDOM.render(<Main />, document.getElementById('main'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="main"/>

I hope it helps. ;)

Upvotes: 1

Austin Greco
Austin Greco

Reputation: 33544

I would do something like this:

const Label = ({ data, attribute, style, link }) => {
  if (link) {
    return (
      <Link to={link} style={style}>{data ? `${data[attribute]}` : ''}</Link>
    );
  }
  // ...
};

You should be able to safely pass undefined as the style prop

Upvotes: 1

Related Questions