Fragments
Fragments are one of React’s most basic components, which allows Component to return multiple elements at once by gathering all the children in a DOM node.
1 2 3 4 5 6 7 8 9 10 | <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token operator"><</span> ChildA <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> ChildB <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> ChildC <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Motivation
We will come up with a specific example as follows
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">class</span> <span class="token class-name">Table</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> table <span class="token operator">></span> <span class="token operator"><</span> tr <span class="token operator">></span> <span class="token operator"><</span> Columns <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> tr <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> table <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
With the above example, Component <Column />
will have the task of returning multiple td
elements at once and if not using Fragment, we will handle how, inherently React’s render function only returns 1 element for a Component
1 2 3 4 5 6 7 8 9 | <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
If we render like that, React will report an error and cannot run.
To solve this problem, we will think of a plan to wrap all the children into a Div
tag like the <Column />
component.
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
It looks ok, guys, but something’s not right here.
We will get the following result:
1 2 3 4 5 6 7 8 9 | <span class="token operator"><</span> table <span class="token operator">></span> <span class="token operator"><</span> tr <span class="token operator">></span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> tr <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> table <span class="token operator">></span> |
This result is really good to run, simply because we have the wrong structure of the Table
, it will not accept Div
cards in tr
cards.
In cases like these, Fragment is the solution that helps us solve this problem.
Usage
We can use fragment to wrap the following components:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Or can be imported as this
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">import</span> <span class="token punctuation">{</span> Fragment <span class="token punctuation">}</span> <span class="token keyword">from</span> React <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> Fragment <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
And the result when using Fragment will be different than we use the Div
tag
1 2 3 4 5 6 7 8 | <span class="token operator"><</span> table <span class="token operator">></span> <span class="token operator"><</span> tr <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> tr <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> table <span class="token operator">></span> |
Short Syntax
For convenience in coding we can use Short Syntax, and it looks like a blank tag
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">Columns</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> Hello <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> td <span class="token operator">></span> World <span class="token operator"><</span> <span class="token operator">/</span> td <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
But note a bit, when you use short syntax, it will not support attribues and keys, so need to consider when using.
Keyed Fragments
Fragment with full syntax declaration will support key and some attributes. If you use it in mapping collection, you should use fragment with full syntax to apply key, this will make the app’s performance increase.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <span class="token keyword">class</span> <span class="token class-name">UserList</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"Jack Bauer"</span> <span class="token punctuation">,</span> email <span class="token operator">:</span> <span class="token string">" <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> "</span> <span class="token punctuation">,</span> phone <span class="token operator">:</span> <span class="token string">"+358509283928"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"Tony Almeida"</span> <span class="token punctuation">,</span> email <span class="token operator">:</span> <span class="token string">" <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> "</span> <span class="token punctuation">,</span> phone <span class="token operator">:</span> <span class="token string">"+358508829378"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"Chloe O'brian"</span> <span class="token punctuation">,</span> email <span class="token operator">:</span> <span class="token string">" <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> "</span> <span class="token punctuation">,</span> phone <span class="token operator">:</span> <span class="token string">"+358508899012"</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> users <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token parameter">user</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator"><</span> React <span class="token punctuation">.</span> Fragment key <span class="token operator">=</span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> id <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span> h2 <span class="token operator">></span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> h2 <span class="token operator">></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> email <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> p <span class="token operator">></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> phone <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> React <span class="token punctuation">.</span> Fragment <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Conclusion
In this article, we have learned about React’s problem when rendering multiple child elements at once and how to solve that problem using Fragment.