Skip to content

Instantly share code, notes, and snippets.

@tidusia
Created December 22, 2021 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tidusia/287461597040ef0718db9f05da2a5cdb to your computer and use it in GitHub Desktop.
Save tidusia/287461597040ef0718db9f05da2a5cdb to your computer and use it in GitHub Desktop.
Context based Compound Component example
// Flexible Compound Components - epicreact.dev
import * as React from 'react'
import {Switch} from '../switch'
// 📜 https://reactjs.org/docs/context.html#reactcreatecontext
const ToggleContext = React.createContext()
ToggleContext.displayName = 'ToggleContext'
function Toggle({children}) {
const [on, setOn] = React.useState(false)
const toggle = () => setOn(!on)
return (
<ToggleContext.Provider value={{on, toggle}}>
{children}
</ToggleContext.Provider>
)
}
function useToggle(componentName) {
const context = React.useContext(ToggleContext)
if (!context)
throw new Error(`${componentName} must be used as a child of Toggle`)
return context
}
function ToggleOn({children}) {
const {on} = useToggle('ToggleOn')
return on ? children : null
}
function ToggleOff({children}) {
const {on} = useToggle('ToggleOff')
return on ? null : children
}
function ToggleButton(props) {
const {on, toggle} = useToggle('ToggleButton')
return <Switch on={on} onClick={toggle} {...props} />
}
function App() {
return (
<div>
<Toggle>
<ToggleOn>The button is on</ToggleOn>
<ToggleOff>The button is off</ToggleOff>
<div>
<ToggleButton />
</div>
</Toggle>
</div>
)
}
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment