React allows you to build very complex applications. But as your applications grow in size, your code can become messy and difficult to build on.
Sometimes, we’d like to split different React components into logically separated files. This act of separating functionality is a common operation in almost any programming language, from Python to C++.
In this article, we will cover how to split React components into different files, and enable them to reference each other. By the end of this article, you’ll know how to import class components and functional components in React as well as understand a key limitation.
Background: Multi-file JavaScript
Since React is a JavaScript library, much of the programming is done in the exact same way across the two. Imports are no exception.
We’ll see a quick example of importing functions and classes from other files in JavaScript below:
In a file named importFrom.js:
function printToScreen( message ) {
console.log( message );
}
export { printToScreen }
Then, in a file named import.js:
import { printToScreen } from "./importFrom";
printToScreen( "Test Message" )
When import.js is run, “Test Message” is logged to the console. Let’s walk through the different key parts of this example.
In importFrom.js, we define the function printToScreen as you’d expect, with a very simple execution. Then, we use the keyword “export” followed by a set of curly braces “{}” with the function printToScreen within.
This exposes the function printToScreen to the directory, so that other files can reference the function. Then, in import.js, we use the “import” keyword to reference the printToScreen function in importFrom.js.
Notice how we use curly braces “{}” here as well, and put the function we’d like to import, printToScreen, within. This allows us to reference the function as if it was written directly in the file.
Notice also how we use the relative path of the file, “./importFrom”. This means that we are importing from the same directory.
We then use the function we imported to print “Test Message” to the console.
Functional Component Imports in React
In React, importing is the same as in vanilla JavaScript. Let’s do a similar example to the one above, but instead of printing “Test Message” to the console, we’ll render it to the screen:
In the file App.js automatically generated by the create-react-app command:
import { ImportComponent } from './ImportElement';
function App() {
return (
<ImportComponent />
);
}
export default App;
Then, in a file called ImportElement.js in the same directory:
function ImportComponent() {
return (
<div>
Test Message
</div>
)
}
export { ImportComponent }
We can see many similarities when importing the functional component ImportComponent. The import and export keywords are used in the exact same way.
Since we are using JSX, we can call ImportComponent just by typing “<ImportComponent />”, rather than needing to call the function itself explicitly.
Of course, there is a difference in ImportElement.js as well, as the function must return a JSX component instead of just printing to the console.
Otherwise, we see that the React and JavaScript imports are identical.
Class Component Imports in React
What about class component imports?
We’ll first see an example in vanilla JavaScript:
As before, we start with a file called importFrom.js:
class printToScreen {
constructor( message ) {
console.log( message );
}
}
export { printToScreen }
And a file called import.js:
import { printToScreen } from "./importFrom";
var printToScreenElem = printToScreen( "Test Message" );
As before, when import.js is run, “Test Message” is logged to the console.
And as before, the import process is identical in React:
In App.js:
import { ImportComponent } from './ImportElement';
function App() {
return (
<ImportComponent />
);
}
export default App;
In ImportElement.js:
import React from "react";
class ImportComponent extends React.Component {
render() {
return (
<div>
Test Message
</div>
);
}
}
export { ImportComponent }
Once again, since we are using React and JSX, the creation and calling of the class ImportComponent is different.
However, the export and import process is identical as in vanilla JavaScript.
Here’s what the output looks like:
Importing from Another Directory in React
So far, we’ve been exporting and importing from the same directory. What if we have subdirectories that we want to pull React component definitions from?
All we have to do is change the path of the file we are importing from. This element is located in a subdirectory called “importSubdirectory”, and the file is called ImportElement.js:
import React from "react";
class ImportComponent extends React.Component {
render() {
return (
<div>
Test Message
</div>
);
}
}
export { ImportComponent }
We import this class component from App.js, which is in the default directory:
import { ImportComponent } from './importSubdirectory/ImportElement';
function App() {
return (
<ImportComponent />
);
}
export default App;
As you can see, all we did was change the path we import from in App.js! The output is the same as before:
What if App.js was located in “importSubdirectory” instead, and ImportElement.js in the default directory? All we’d have to do is change the path in App.js once again:
import { ImportComponent } from '../ImportElement';
function App() {
return (
<ImportComponent />
);
}
export default App;
In the example above, we changed the path to “../ImportElement” instead.
If you’re unfamiliar with the ‘..’ before the first slash, all it does is navigate one directory upward. So rather than importing from the directory “/importSubdirectory/”, we import from the root directory, “/”, where ImportElement.js is located.
The output is exactly the same:
Import Limitations in React
There is a key import limitation in React which we haven’t discussed thus far: you cannot import from files outside the src directory. The src directory is created by ‘create-react-app’, and is meant to encompass all React files in your application.
With the file structure below:
We cannot import from the file importError.js from within the ‘src’ directory. If we try to do so in App.js:
import { ImportComponent } from '../../importError';
function App() {
return (
<ImportComponent />
);
}
export default App;
We’ll encounter the following error in the console: “Module not found: You attempted to import ../../importError which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.”
This means that if you have any existing JavaScript code you’d like to integrate with React, you have to place the entire source code within the ‘src’ directory in your React app, and work from there.
So long as you keep all your files within the ‘src’ directory, React imports are powerful and straightforward, working exactly like their vanilla JavaScript counterparts.
I hope you enjoyed learning how to import components in React! If you have any questions or comments, please leave them below.
💬 Leave a comment