React Tips — Component Organization
Tags: webdev, programming, javascript, react
Published: 2021-01-23 19:51:39

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at ways to organize our component structure to make maintenance easy.

### Container and Presentational Components

We should separate our components for doing logic from the ones that are presenting the data. This keeps components small and easy to test. Testing presentational components is easy since all they do is get data and present them.

Container components don’t render anything presentational, so we only have to check the logic. Therefore, testing container components would be easy as we only have to test the logic.

For instance, we can write the following code to organize our components into a container and presentational component:

```
import React, { useEffect } from "react";

const Result = ({ result }) => {
  return <p>{result.name}</p>;
};

export default function App() {
  const [result, setResult] = React.useState({});
  const getResult = async () => {
    const res = await fetch(`https://api.agify.io?name=michael
    `);
    setResult(await res.json());
  };

  useEffect(() => getResult(), []);
  return <Result result={result} />;
}
```

In the code above, `App` is the container component for `Result` . `Result` just displayed what’s passed in from `App` , while `App` has the logic to get the data that we want to display in `Result` by passing the retrieved data via props.

### Portals

Portals are a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is convenient for creating things like modals and anything that we want to put outside of the normal DOM hierarchy.

We can create a component that mounts a component in a DOM element of our choice as follows:

`index.html` :

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <title>React App</title>
  </head>

  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <div id="foo"></div>
  </body>
</html>
```

`index.html` :

```
import React from "react";
import ReactDOM from "react-dom";

const Portal = ({ children }) => {
  const domNode = document.getElementById("foo");
  return ReactDOM.createPortal(children, domNode);
};

export default function App() {
  return (
    <Portal>
      <p>foo</p>
    </Portal>
  );
}
```

In the code above, we have the `Portal` component that returns:

```
ReactDOM.createPortal(children, domNode);
```

The code above mounts our `children` into the DOM Node of our choice, which is the div with the ID `foo` .

Then in `App` , we render the `Portal` component with the p element with text ‘foo’.

Therefore, we’ll see the word ‘foo’ display on the screen and the p element with that text is a child of the div with ID `foo` instead of being the child of the div with ID `root` , which is the mount point of our app.

### Code Splitting

By default, a built React app is loaded all at once. This means that no matter how big it is, it’s downloaded and run in the browser as one big package.

Even though lots of people have fast internet now, this may still be a problem for lots of people around the world with slow connections. To make code load in small pieces asynchronously, we can use code-splitting to load a React app in pieces.

We can do code-splitting with Create React App by using the Webpack’s `import` function and providing a component to load when the actual component is loading.

For instance, we can use the `import` function, the `React.lazy` method, and `React.Suspense` component to create make components load when it’s needed instead of loading immediately as follows:

`Foo.js` :

```
import React from "react";

export default function Foo() {
  return <p>foo</p>;
}
```

`App.js` :

```
import React, { Suspense } from "react";
const Foo = React.lazy(() => import("./Foo"));

export default function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Foo />
    </Suspense>
  );
}
```

In the code above, we moved the component that we want to load on demand into its own module. Then we import it with:

```
const Foo = React.lazy(() => import("./Foo"));
```

instead of a normal ES import.

Then in `App` , we use the `Suspense` component that’s provided by React and pass a fallback component to show when the component is loading into the `fallback` prop.

Inside the `Suspense` component, we put the component we actually want to show inside.

Therefore, we’ll see ‘Loading…’ when `Foo` is loading, then ‘foo’ is shown.

### Conclusion

To make testing and maintenance easy, we should organize our code into container components that have logic and presentation components that are only used to display items.

To mount the React component outside of its usual location, we can render portals to mount our React components anywhere we want.

Finally, to make React load in pieces when it’s needed instead of loading everything at once, we can use code-splitting to load components on demand.