Component Principles
Component Principles
- Keep it stupid
- Keep it scoped
Keep it stupid
- Solve one problem well
- Functionally pure
- Self-contained (No side-effects)
- Handle basic html attributes (className)
Solve one problem well
- Style is a problem
- Behavior is a different problem
- Different components should solve each
- Composing them can be another problem
Functionally pure
- Should return the same thing for a given set of props
Self-contained (No side-effects)
- Don't modify things outside of itself
- Side-effects are their own problem
Handle basic html attributes
- If it's just an opinionated html element, it should accept all attributes that element could accept
const Button = ({ children, ...props }) => (
<StyledButton {...props} >{ children }</StyledButton>
)
Keep it scoped
- Styles itself, Positions its children
- Props and hooks only
- Encapsulate opinion. Then compose.
Styles itself, Positions its children
- A child's style is its own problem to solve
- A child's position is a problem for the parent to solve
.component {
& > .component-part {
margin: auto;
}
}
Props and hooks only
- Should be pure functions
- Deterministic
- No Side Effects
- Avoid globals
- Avoid unconventional methods
- useRef
- React.children
Encapsulate opinion. Then compose.
const Contrived = () => {
const foo = useFoo()
const bar = usebar()
return (
<div>
<h1>{foo}</h1>
<button onClick={bar}>Submit</button>
</div>
)
}
Encapsulate opinion. Then compose.
const useContrivedData = () => {
const foo = useFoo()
const bar = usebar()
return {
foo,
bar,
}
}
const _Contrived = ({ foo, bar = () => {} }) => (
<div>
<h1>{foo}</h1>
<button onClick={bar}>Submit</button>
</div>
)
const Contrived = () => {
const data = useContrivedData()
return </ {...data} _Contrived>
}
deck
By Matthew Poulson
deck
- 55