Search code examples
reactjs

Map over Fragment in React 16


I am trying to map over the children of a fragment that is in turn a child of a component. For example:

const Frag = () => (
  <React.Fragment key="test-key">
    <div>test1</div>
    <div>test2</div>
  </React.Fragment>
);

const Outer = ({ children }) => (
  <div>
    {
      React.Children.map(children, (child) => (
        <a>
          {child}
        </a>
      ))
    }
  </div>
);

// Usage
<Outer>
  <Frag />
</Outer>

This will result in a single a tag even though the fragment has multiple divs inside of it. The docs (https://reactjs.org/docs/react-api.html#reactchildrenmap) seem to indicate that this should work with a keyed fragment and I think I am creating a keyed fragment correctly (https://reactjs.org/docs/fragments.html#keyed-fragments). Any help would be appreciated!


Solution

  • Yes, but as far as I can see - you are iterating over Outer children. Try to

    React.Children.map(children[0].props.children, (child) => (
    

    But, looking closely at your links - I see that documentation says something wrong here

    the function will never be passed the container objects

    Here is an example, which clearly shows that container is passed to the function:

    <script src="https://unpkg.com/@babel/standalone/babel.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
    <div id="root" />
    <script type="text/babel">
      const Frag = () => (
        <>
          <div>test1</div>
          <div>test2</div>
        </>
      ); 
      
      const Outer = ({ children }) => (
        <div>
          { 
            React.Children.map(children, (child) => console.log(`Child type is ${child.type.name || child.type.toString()}`) || (
            <a>
              {child}
            </a> )) 
          }
        </div>
      ); 
      
      
      ReactDOM.render((
        <div>
          <Outer>
            <>
              <div>test1</div>
              <div>test2</div>
            </>
          </Outer>
          <Outer>
            <Frag />
          </Outer>
        </div>
      ), document.getElementById('root'));
    </script>