Is there a way to make separate files for components such as logic, html and CSS in ReactJS like Angular?

Viewed 131

I am completely new to ReactJS. I have previously worked in Angular for my office work and I liked the way it is so much organised as the logic files (component.ts or module.ts, scss and HTML) files are separate. I have been started to watch a react tutorial on youtube and saw they styling, logic and HTML are inside the same file. I know that that is not actually HTML. But is there a proper way to keep those codes in separate files like angular?

Thanks in advance.

1 Answers

It's quite possible, you just need to set up your environment to support it.

Let's say you want to separate things as much as possible - you want the functions associated with a component to be in one file, the JSX associated with the component in another, and the CSS in another. To start with, you'll need a module bundler like Webpack, which your React installation may already have integrated. A module bundler allows you to take multiple separate files in a project and compiles them together into a single (or multiple, if you wish) file for production.

To bundle all CSS into a single file with Webpack, see MiniCssExtractPlugin and use the option chunks: "all" in your Webpack config. Then you can import CSS files in your JavaScript. For example:

// componentA.jsx
import './styleA.css';
// other componentA JS code...
// componentB.jsx
import './styleB.css';
// other componentB JS code...

can be used to write your styles for componentA and componentB in separate files, import them via the JS, and Webpack will transform it into a single usable CSS file for production.

If you don't want Webpack to merge everything into a single CSS file, that's easy to manage too - that's what the plugin does by default.

You can easily integrate CSS preprocessors like SCSS if you want.

In the component's JavaScript, you're free to import functions from other files. eg:

// ComponentA.jsx
import './styleA.css';
import { makeApiCall } from './makeApiCall.js';

export const ComponentA = (props) => {
  const [callMade, setCallMade] = useState(false);
  const handler = () => makeApiCall().then(() => setCallMade(true));
  return (
    <button onClick={handler}>{callMade}</button>
  );
};

allowing you to separate out the JavaScript logic, and the JavaScript logic from the component's JSX as much as desired.

A word of caution, though. Putting related functions in separate files can increase boilerplate to an undesirable level. For example, if you have multiple states, and you'd want a few functions to all have access to those multiple states and be able to set them, you'd have to pass all those values to the functions when calling them. Eg

const [stateVal1, setStateVal1] = useState(
const [stateVal2, setStateVal2] = useState(

If you had two functions that needed both of these states and their setters, and the functions are in separate files, you'd need something like

importedFn1(stateVal1, setStateVal1, stateVal2, setStateVal2);
importedFn2(stateVal1, setStateVal1, stateVal2, setStateVal2);

Kind of ugly. I'd recommend:

  • Abstracting into separate files functionality that doesn't have to do with React - such as API calls. For React code, like state and state setters, having those written out in the component itself could well be easier. (so you can do things like const handler = () => makeApiCall().then(() => setCallMade(true)); as shown above)
  • If the component gets too long to be reasonably understood as a whole easily, consider creating sub-components in separate files rather than trying to figure out a way to put everything into a single component manageably.
Related