I’m a front-end developer and designer based in Fort Worth, TX with a passion for web technologies, inclusivity, and Texas BBQ. I currently help make the space that comes from The Container Store.
One of the rules I try to follow is don’t make something a shared component until I’ve copied and pasted it four times. Too often I would create components too early, without any context beyond the current one. This would lead to components with awkward and bloated APIs from other developers trying to adapt it to their needs.
Also, if your component encapsulates complicated code structure, offer a way for developers to get to the individual components. For example, say you’ve created an Input component that renders a label and control, as well as an error message on invalid input. Give developers a way to access the individual components and allow them to completely recompose (or add to) the component’s structure if they have to.
Some library APIs give you render props for each component, but that quickly gets messy when you have to add a labelRender, a controlRender, and an errorRender. I personally like compound components exported from the original component (e.g. <Input.Label>), along with React Context providing the necessary linking state (e.g. the input’s ID for the label’s htmlFor prop).
I... don’t make something a shared component until I’ve copied and pasted it four times... This would lead to components with awkward and bloated APIs from other developers trying to adapt it to their needs.
The problems with this are:
Your duplicated code likely has minor updates in each iteration, instead of refininements to a 'common component'. Now it is more difficult to unify them.
If you needed the same functionality 4 times, it's likely other team devs did as well. Since there was no common component, each had to reinvent the wheel, each time with different API's. Now it's very difficult to unify all these components to use the same common one, along with all their tests. This is so much work that it usually is never done, and the duplicated code remains, complicating future enhancements and maintenance.
I find it best to create common components as early as possible, then encourage reuse rather that duplication, (DRY). Common components should evolve as new needs arise; this is agile coding! Even heavily used libraries like MaterialUI are updated regularly, so your own 'library' of components should be as well.
Good code reviews can prevent overcomplicating common components. Guidelines like the ones in this article, along with app standards, also help keep API's simple and consistent across an app. It's easier to refactor a common component occasionally than to replace totally different implementations of the same functionality.
I’m a front-end developer and designer based in Fort Worth, TX with a passion for web technologies, inclusivity, and Texas BBQ. I currently help make the space that comes from The Container Store.
I agree that good code reviews can prevent over complicating common components, but I’m not as concerned with reinventing the wheel, at least not at first. I believe components need to earn their right to exist, and by the time they have earned this right, you typically have a good starting point for an API, and a good reviewer can pick this out.
Also, in my experience, if I am having difficulty unifying components into a common component, there’s a good chance they aren’t as common as I might have originally thought. I may be better served in extracting out common related logic into a helper function or hook.
With the projects I work on at work, I tend to fall on the side of making code as disposable as possible, so take what I’m with a grain of salt. I am very hard on what makes its way into our shared common components.
Honestly, whatever works for you is great, especially since this is one of those areas where it depends a lot on the context of the work.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
One of the rules I try to follow is don’t make something a shared component until I’ve copied and pasted it four times. Too often I would create components too early, without any context beyond the current one. This would lead to components with awkward and bloated APIs from other developers trying to adapt it to their needs.
Also, if your component encapsulates complicated code structure, offer a way for developers to get to the individual components. For example, say you’ve created an
Input
component that renders a label and control, as well as an error message on invalid input. Give developers a way to access the individual components and allow them to completely recompose (or add to) the component’s structure if they have to.Some library APIs give you render props for each component, but that quickly gets messy when you have to add a
labelRender
, acontrolRender
, and anerrorRender
. I personally like compound components exported from the original component (e.g.<Input.Label>
), along with React Context providing the necessary linking state (e.g. the input’s ID for the label’shtmlFor
prop).The problems with this are:
I find it best to create common components as early as possible, then encourage reuse rather that duplication, (DRY). Common components should evolve as new needs arise; this is agile coding! Even heavily used libraries like MaterialUI are updated regularly, so your own 'library' of components should be as well.
Good code reviews can prevent overcomplicating common components. Guidelines like the ones in this article, along with app standards, also help keep API's simple and consistent across an app. It's easier to refactor a common component occasionally than to replace totally different implementations of the same functionality.
I agree that good code reviews can prevent over complicating common components, but I’m not as concerned with reinventing the wheel, at least not at first. I believe components need to earn their right to exist, and by the time they have earned this right, you typically have a good starting point for an API, and a good reviewer can pick this out.
Also, in my experience, if I am having difficulty unifying components into a common component, there’s a good chance they aren’t as common as I might have originally thought. I may be better served in extracting out common related logic into a helper function or hook.
With the projects I work on at work, I tend to fall on the side of making code as disposable as possible, so take what I’m with a grain of salt. I am very hard on what makes its way into our shared common components.
Honestly, whatever works for you is great, especially since this is one of those areas where it depends a lot on the context of the work.