DEV Community

Discussion on: The Anatomy Of My Ideal React Component

Collapse
 
well1791 profile image
Well

I love twin.macro but I'm more of a stitchesjs guy, which btw twin.macro already supports, and I'm going to provide an example for it.

Also, I believe there's a nicer approach to that repetitive conditional sequence if error then <Error /> else if isLoading then <Loading /> else if data then <Component /> else <Empty /> check redwoodjs approach redwoodjs.com/docs/cells, in short, you just have a wrapper smart enough to deal with all that logic.

I agreed with pretty much everything, but types must be moved in a separated file, also, the component tag type must be exported along with the component props (for a11y). And, when it comes to the folder structure, I prefer styles in a separated file over "styled-components" in the same file. Let me elaborate more on this.

/// folder structure
- src/components/Post/Post.tsx
- src/components/Post/PostStyles.ts
Enter fullscreen mode Exit fullscreen mode

where

/// src/components/Post/Post.tsx
import * as stl from './PostStyles'
import type { PostProps } from './PostTypes'

export const Post: React.FC<PostProps> = ({ data, ...p }: PostProps) => {
  return (
    <div {...p} className={stl.container({ className: p.className })}>
      ...
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Then all you have to do, is work your styles in a separated file!

/// src/components/Post/styles.ts
import { css } from 'src/shared/theme'

export const container = css({
  $$minHeight: 'inherit', // <- stitchesjs magic
  bg: '$blue100',
  h: '$$minHeight,
})
Enter fullscreen mode Exit fullscreen mode

Now! Where is the fun?

  1. Your Post component now displays only markup content! No need to have a bunch of "mini components" with styles listed in the same file.
  2. You can now see the html tag name instead of some random (and sometimes silly) name! Which means, now you have a better experience with a11y
  3. If for some reason you need to override the style of an inner component! You could just override it by using styles only! No need to pass some new props everywhere!
/// src/component/BigFun/styles.tsx
import * as postStl from 'src/components/Post/PostStyles'

export const container = css({
  [`.${postStl.container()}`]: {
    $$minHeight: '100%',
  },
})
Enter fullscreen mode Exit fullscreen mode

But! I know, I know, you're think "wtf? how do I change things programmatically in the PostStyles.ts file?" Aaaaand!! Here's where stitches shines: stitches.dev/docs/variants ๐ŸŽ‰ ๐Ÿคท everything is typed and everyone is happy! (for now... ๐Ÿคจ)

Collapse
 
antjanus profile image
Antonin J. (they/them)

After reading your comment about splitting everything up, I'm wondering if I'm mildly biased toward bigger components because I just legit use a bigger monitor ๐Ÿ˜‚