DEV Community

Cover image for Working with React Fragments, Portals and Ref's
Emmanuel Effiong
Emmanuel Effiong

Posted on

Working with React Fragments, Portals and Ref's

React Fragments

In React, we work with JSX, jsx is that code which you return from your react component. Here is an example
jsx-example @emmalegend
The limitation with JSX is that, you cannot return multiple root jsx, and it has to be just one. This is a JavaScript feature because you can only return one thing.
This image will throw an error
errror-jsx
Before now, the work around for someone like me and others was to wrap my content with inside another div and make it the only root component.
root-div @emmalegend
Now, this is totally fine and will work well, but when you have many nested div's that are returning another unnecessary div and its being rendered to the DOM, it leads to something called the DIV soup..
div soup
Basically this isn't good for Accessibility and this could break your styling., and rendering unwanted content in react isn't also good for your react performance.
The best solution is what React provided for us, React.Fragment and this is how to use it. you can either import the name fragment component from React or you use React.fragment or you use the shorthand version of it.
react-fragment
At the end it saves us the stress of wrapping our jsx components with unwanted and unnecessary divs and also render a clean HTML code to the DOM.

React Portals

As you know, whatever code you are writing in React gets rendered in DOM through the div with an ID of "root" which is in your index.html file., and the rendering is done in the index.js file which is the entry point.
index
The common use case for React Portal is that, imagine you want to render a component in another place say siblings with the root div(i.e the div with an ID of root) in the DOM and a child of Body Element, without altering where it is written, weather it is deeply nested or not, you need to port the component from where it was originally created to where you want to rendered it to be in the DOM.

So in the image below, the index.html file is where ReactDom will render the HTML code you wrote., and now you want to Render a particular component(say popup) to the div with an ID of "popup".sit to sit as a sibling to the div with the ID of "root".
And you have to explicitely add that div, React won't add it though, 😀
reactportal
If you look at the image below, we imported ReactDOM as a default export, then we created a separate component (The Port component) we want to port.
reactPortal

In the Popup component, we call ReactDom with the createPortal method, the createPortal method expects 2 properties,

  • a React component like the Port Component, this is important so that we can pass props if we need to.

  • A place where we need to port to, here we will get the root element using our javascript document method.

When the component is rendered again, our component that was deeply nested will be ported to the sibling of our root div in index.html file.

React Refs

Refs actually allow us to work with other DOM elements, for me i use refs with forms to get the value of the input element in forms. You might ask, why can't we use the onChange event with the event.target.value to get the form input?

For some people, changing the value of an input after each keystroke might not really be what they want, all they need is just to get the value at once.

In the image below, I'll show you how to do that with ease.,
react ref
I first imported the useRef hook from React, and you know we can only use it inside the function since its a functional Hook.
Then I created an instance of it and store it in a constant called nameInput.

In the Input element, react has a prop called ref which references a pointer, our pointer in this case is the name of our instantiated hook, which is called nameInput.

nameInput returns an object that contains the current property which also contain the value property that holds the value of the input

The nameValue constant contains the value of our input element when rendered but will do this once and not after each keystroke.

Top comments (0)