8

I have some repetitive code which renders some html in a React component. I would like to store the repetitive html elements in a variable and return them but am unable to do this.

const renderAddress = event => {
  if (event.venue.address.address_2) {
    return (
      <address>
        {event.venue.address.address_2}
        <br />
        {event.venue.address.address_1}
        <br />
        {event.venue.address.city}
        <br />
        {event.venue.address.postal_code}
      </address>
    )
  } else {
    return (
      <address>
        {event.venue.address.address_1}
        <br />
        {event.venue.address.city}
        <br />
        {event.venue.address.postal_code}
      </address>
    )
  }
}

Ideally I would like something like this:

const renderAddress = event => {
  const base = (
        {event.venue.address.address_1}
        <br />
        {event.venue.address.city}
        <br />
        {event.venue.address.postal_code}
        )
  if (event.venue.address.address_2) {
    return (
      <address>
        {event.venue.address.address_2}
        <br />
        {base}
      </address>
    )
  } else {
    return (
      <address>
        {base}
      </address>
    )
  }
}

2 Answers 2

9

Your ideal approach seems like a great way to compose the final <address> element. You can achieve this using Fragments as the issue/error would be around base's contents in renderAddress(event) would need to be wrapped with some element to avoid errors attempting to render values such as {event.venue.address.address_1}. A React.Fragment would allow you to render base while avoiding introducing additional rendered wrapper elements:

const renderAddress = event => {
  const base = (
    <React.Fragment>
      {event.venue.address.address_1}
      < br />
      {event.venue.address.city}
      < br />
      {event.venue.address.postal_code}
    </React.Fragment>
  );

  if (event.venue.address.address_2) {
    return (
      <address>
        {event.venue.address.address_2}
        <br />
        {base}
      </address>
    );
  } else {
    return (
      <address>
        {base}
      </address>
    );
  }
};

Here is a basic example in action.

Note: React.Fragment is only available with React version 16.2+.

Sign up to request clarification or add additional context in comments.

Comments

3

I like JSX and the ways you can manipulate it, so, thought I'd post an answer, too.

Use a combination of an array, which is easy to manipulate, and native JSX-rendering, like so...

const renderAddress = event => {
  var address_pieces = [];

  if (event.venue.address.address_2) {
    address_pieces.push(event.venue.address.address_2);
  }

  address_pieces.push(event.venue.address.address_1);
  address_pieces.push(event.venue.address.city);
  address_pieces.push(event.venue.address.postal_code);

  return (
    <address>
      {address_pieces.map(address_piece => {
        return (
          <span>
            {address_piece}
            <br />
          </span>
        );
      })}
    </address>
  );
};

This removes the redundant parts of your code, and gives you some new JS tools to work with, like map().

I have also coded up a full, working sample here: https://codesandbox.io/s/r1w60ozo3o

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.