javascriptreactjssetiterationjsx

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.


Solution

  • 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>
    ))}