Skip to content

Instantly share code, notes, and snippets.

@mattmccray
Last active November 7, 2019 04:04
Show Gist options
  • Save mattmccray/fef509e5e87ca6344ae184204683a204 to your computer and use it in GitHub Desktop.
Save mattmccray/fef509e5e87ca6344ae184204683a204 to your computer and use it in GitHub Desktop.
Proposal for a .react single file component that doesn't suck.
<script>
import React from 'react'
import styles from './'
export default () => {
const [items, setItems] = React.useState([{id:1, text: 'First'}])
return (
<div className={styles.Test}>
<header>This is a Test</header>
<ul>
{items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
</div>
)
}
</script>
<style>
.Test {
padding: 12px;
}
.Test header {
color: dodgerblue;
}
</style>
@mattmccray
Copy link
Author

mattmccray commented Oct 25, 2019

It should be somewhat straightforward to implement support for this in a build tool like Webpack.

The tricky bit is the import styles from '"/", and I'm not sure that's the right way to go. Instead we could inject a Styles object into the script block at build time. Or perhaps we don't worry about scoping/modules and just treat it as straight CSS:

<script>
import React from 'react'

export default (props) => (
  <button className="MyButton">{props.children}</button>
)
</script>

<style>
.MyButton { background-color: dodgerblue; }
</style>

I lean towards the latter, as it's simpler. And it doesn't prevent, or complicate, support for TypeScript in the script block.

<script type="text/typescript">
import React from 'react'

type MyButtonProps { children?: React.ReactNode }

export default (props: MyButtonProps) => (
  <button className="MyButton">{props.children}</button>
)
</script>

<style>
.MyButton { background-color: dodgerblue; }
</style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment