|
4 | 4 | import * as React from 'react' |
5 | 5 | import {Switch} from '../switch' |
6 | 6 |
|
7 | | -// 🐨 create your ToggleContext context here |
8 | | -// 📜 https://reactjs.org/docs/context.html#reactcreatecontext |
| 7 | +const ToggleContext = React.createContext(0) |
9 | 8 |
|
10 | 9 | function Toggle({children}) { |
11 | 10 | const [on, setOn] = React.useState(false) |
12 | 11 | const toggle = () => setOn(!on) |
13 | 12 |
|
14 | | - // 🐨 remove all this 💣 and instead return <ToggleContext.Provider> where |
15 | | - // the value is an object that has `on` and `toggle` on it. |
16 | | - return React.Children.map(children, child => { |
17 | | - return typeof child.type === 'string' |
18 | | - ? child |
19 | | - : React.cloneElement(child, {on, toggle}) |
20 | | - }) |
| 13 | + const value = {on, toggle} |
| 14 | + |
| 15 | + return ( |
| 16 | + <ToggleContext.Provider value={value}>{children}</ToggleContext.Provider> |
| 17 | + ) |
| 18 | +} |
| 19 | + |
| 20 | +const useToggle = () => { |
| 21 | + const context = React.useContext(ToggleContext) |
| 22 | + if (!context) { |
| 23 | + throw new Error('useToggle must be used within a <Toggle/>') |
| 24 | + } |
| 25 | + return context |
21 | 26 | } |
22 | 27 |
|
23 | 28 | // 🐨 we'll still get the children from props (as it's passed to us by the |
24 | 29 | // developers using our component), but we'll get `on` implicitly from |
25 | 30 | // ToggleContext now |
26 | 31 | // 🦉 You can create a helper method to retrieve the context here. Thanks to that, |
27 | 32 | // your context won't be exposed to the user |
28 | | -// 💰 `const context = React.useContext(ToggleContext)` |
| 33 | + |
29 | 34 | // 📜 https://reactjs.org/docs/hooks-reference.html#usecontext |
30 | | -function ToggleOn({on, children}) { |
| 35 | + |
| 36 | +function ToggleOn({children}) { |
| 37 | + const {on} = useToggle() |
31 | 38 | return on ? children : null |
32 | 39 | } |
33 | 40 |
|
34 | 41 | // 🐨 do the same thing to this that you did to the ToggleOn component |
35 | | -function ToggleOff({on, children}) { |
| 42 | +function ToggleOff({children}) { |
| 43 | + const {on} = useToggle() |
36 | 44 | return on ? null : children |
37 | 45 | } |
38 | 46 |
|
39 | 47 | // 🐨 get `on` and `toggle` from the ToggleContext with `useContext` |
40 | | -function ToggleButton({on, toggle, ...props}) { |
| 48 | +function ToggleButton({...props}) { |
| 49 | + const {on, toggle} = useToggle() |
41 | 50 | return <Switch on={on} onClick={toggle} {...props} /> |
42 | 51 | } |
43 | 52 |
|
44 | | -function App() { |
| 53 | +// const App = () => <ToggleButton /> |
| 54 | + |
| 55 | +const App = () => { |
45 | 56 | return ( |
46 | 57 | <div> |
47 | 58 | <Toggle> |
|
0 commit comments