Demian Sims
Demian Sims

Reputation: 921

Iteration over Set in React component won't render in JSX

I'm trying to iterate over a javascript Set() passed down in props inside a React component. I can't anything to render on the screen with the iteration in place:

 {selectedCity.forEach((key, value) => (
          return (
            <Row>
              <Col sm={12} md={6} mdOffset={4} lgOffset={4}>
                <Typography className="hide-mobile" h3>
                  TICKET PRICE FOR IN-STATE:
                </Typography>
                <Typography h3>{value.name}</Typography>
                <TicketPriceInput
                  onChange={e => {
                    setConcertDetails('price', e.target.value);
                    detectInputChange(e);
                  }}
                  value={price}
                  name="price"
                  isPriceChanged={isPriceChanged}
                />
                <OutPriceLabel className="hide-mobile">
                  <Typography h3>TICKET PRICE FOR OUT-OF-STATE:</Typography>
                  <Typography h3 bold className="hide-mobile">
                    {outLocationPrice()}
                  </Typography>
                </OutPriceLabel>

                <FootNote>
                  <Typography medium spaced className="hide-mobile">
                    *After the first 20 tickets anyone located in-state can
                    purchase tickets at the regular ticket price you set.
                  </Typography>
                </FootNote>
              </Col>
            </Row>
          );
        ))}

I've done this plenty of times with an Array or Object with map() or Object.keys() and it's worked.

Upvotes: 3

Views: 5117

Answers (2)

Ori Drori
Ori Drori

Reputation: 191946

The Set.forEach() method iterates the Set's values, but doesn't return anything.

One option is to push the created elements to an array, and then return the array:

const renderSelectedCity = selectedSet => {
  const rendered = [];

  selectedSet.forEach(value => {
    rendered.push(
      <Row key={value.id}>
      // your JSX
      </Row>
    );
  });

  return rendered;
};

And then you can use it by calling the function, and supplying the Set:

{renderSelectedCity(selectedCity)}

The other option is to spread the Set to an array, iterate the array with Array.map() that would return a new array of rendered elements:

{[...selectedCity].map(value => (
  <Row key={value.id}>
  // your JSX
  </Row>
))}

You can also use Array.from() to create a JSX array from the Set:

Array.from(selectedCity, value => (
  <Row key={value.id}>
  // your JSX
  </Row>
))}

Upvotes: 3

Nahuel
Nahuel

Reputation: 171

You have to use map. That's because map will return the component, but forEach will not. map is an array method, not available in Sets. but you can easily map over the set by using Array.from (which will convert the Set into an Array)

Array.from(selectedCity).map(...)

Upvotes: 9

Related Questions