How to organize styled components in React App with Typescript

Yevhen Kazmirchuk
4 min readApr 16, 2022

--

Hey, in this article, I’ll show you the best way of working with “styled-components”, and explain why and how. But, if you are interested only in the final example, click on this link.

🗒️ Problems:

  • 📌 Flexibility — we should be able to increase the number of “styled-components” without additional effort and make supporting easy;
  • 📌 Readability — code should be readable and easy to reach;
  • 📌 Importing — no chaos in imports. Other components should not have direct access to any “styled-components”;
  • 📌 Filtering — we need to understand where “styled-components” and “react-component”, are without spending additional time.
  • 📌 Modifying — be able to refer to others' “styled-components” . If you do not understand what I am talking about, you really should get familiar with this powerful feature https://styled-components.com/docs/advanced#referring-to-other-components

Solution 1

It’s easy to create, no additional effort, but will be challenging to maintain if the “react-component” will grow up, best fit for small unchangeable components, like <Button /> or <Input />

As you can see, here we have some naming convention, which allows us to distinguish “styled-components” and “react-components”, but styles and business logic in the same place, and if you know that component will become bigger and bigger, that’s not your option.

Check List:

  • Flexibility:
  • Readability: DEPENDS
  • Importing:
  • Filtering: ✅
  • Modifying: ❌

Solution 2

We can create a separate file to fix maintenance problems and put all our “styled-components” there.

MyComponent
— — | MyComponent.tsx
— — | styled.tsx

styled.tsx
MyComponent.tsx

But, we will meet a lot of problems in import. It will not allow you to reuse names for “styled-components” your code assistance will show you results from many other components, and that’s bad because you have to check if the import is correct.

Check List:

  • Flexibility:
  • Readability:
  • Importing:
  • Filtering: ✅
  • Modifying: ✅

Solution 3

In this case, I will show you a few examples, the structure will be the same as in Solution 2, and it will be much more interesting.

MyComponent
— — | MyComponent.tsx
— — | styled.tsx

styled.tsx
MyComponent.tsx

By storing all our “styled-components” inside object “S”, we exclude direct access to non-relative “styled-components”. Also, we have Readability cause we know that “styled-components” will be accessible only through an object “S”.

But there is another problem with the Modification (Referring). Let me explain. A good point is on line 11, in the picture above, if any other component that uses <MyComponent /> will be able to modify it without changing any code inside <MyComponent />, see the example on the screen below.

That is one of the reasons why “styled-component” is widespread, but there is a small issue. As you see <SomeTestComponent /> refer to <MyComponent />, but <MyComponent /> is not able to refer to herself’s “styled-components”, look at the picture below.

styled.tsx

The lack of this feature is not acceptable. A possible workaround is displayed below.

styled.tsx

This will work, but if you have a lot of “styled-component”, it will become your little hell to move all constants to object “S”.

Check List:

  • Flexibility:
  • Readability:
  • Importing:
  • Filtering: ✅
  • Modifying: ✅
  • It becomes time-consuming if you have to add more “styled-components”

Solution 4 (Final one)

This is the best I have found for now, and, unfortunately, it works only with Typescript.

No changes inside the component file. It has no difference from Solution 3

MyComponent.tsx
styled.tsx

With Typescript namespace, you can do what we have planned to do. Let’s move through check.

  • Flexibility: you can easily modify existing “styled-component” or add more once;
  • Readability: it’s easy to read, and you always know where to find your component styles;
  • Importing: you exclude chaos in imports because everything you export from the namespace is accessible only through its namespace;
  • Filtering: you know, that “styled-component” is accessible only through an “S” object;
  • Modifying: you can refer from outside and inside;

Thank you for reading. I hope that will help you make a better structure. If you have any questions, please ask them in the comments.

--

--

Responses (2)