How to organize styled components in React App with Typescript
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
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
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.
The lack of this feature is not acceptable. A possible workaround is displayed below.
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
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.