react context

State

const LightSwitch = () => {
    const [on, setOn] = useState(false);
    
    return (
        <Panel>
            <Switch
                onToggle={() => setOn(!on)}
            />
        </Panel>
    )
}

Prop Drilling

const House = () => {
    const [lights, setLights] = useState({
        livingRoom: false,
        kitchen: true,
        study: false,
        bedroom: false
    });
    
    return (
        <House>
            <GroundFloor
                lights={lights}
                onLightChange={setLights}
            />
            <FirstFloor
                lights={lights}
                onLightChange={setLights}
            />
        </House>
    )
}

Prop Drilling...

const GroundFloor = ({lights}) => {
    return (
        <Rooms>
            <LivingRoom
                light={lights.livingRoom}
            />
            <Kitchen
                light={lights.kitchen}
            />
        </Rooms>
    )
}

Prop Drilling......

const LivingRoom = ({light, onLightChange}) => {
    return (
        <Room>
            <LightSwitch
                on={light}
                onChange={() => onLightChange(!light)}
            />
        </Room>
    )
}

context

const HouseContext = React.createContext({});

const App = () => {
    return (
        <HouseContext.Provider value={{
            livingRoom: false,
            kitchen: true,
            study: false,
            bedroom: false,
            onLightChange: () => {}
        }}>
            <House>
                <GroundFloor/>
                <FirstFloor/>
            </House>
        </HouseContext.Provider>
    )
}

context...

const LivingRoom = () => {
    const lights = useContext(HouseContext);
    return (
        <Room>
            <LightSwitch
                on={lights.livingRoom}
                onChange={() => lights.onLightChange(!light)}
            />
        </Room>
    )
}

context......

const HouseStateContext = React.createContext();
const HouseDispatchContext = React.createContext();

function useHouseState() {
    const context = React.useContext(HouseStateContext)
    if (context === undefined) {
        throw new Error('useHouseState must be used within a HouseProvider')
    }
    return context
}
function useHouseDispatch() {
    const context = React.useContext(HouseDispatchContext)
    if (context === undefined) {
        throw new Error('useHouseDispatch must be used within a HouseProvider')
    }
    return context
}

const App = () => {
    const [state, setState] = useState({})
    return (
        <HouseStateContext.Provider value={state}>
            <HouseDispatchContext.Provider value={setState}>
                <House>
                    <GroundFloor/>
                    <FirstFloor/>
                </House>
            </HouseDispatchContext.Provider>
        </HouseStateContext.Provider>
    )
}

context.........

const LivingRoom = () => {
    const lights = useHouseState();
    const setLights = useHouseDispatch();
    return (
        <Room>
            <LightSwitch
                on={lights.livingRoom}
                onChange={() => setLights(!light)}
            />
        </Room>
    )
}

context............

const MasterSwitch = () => {
    const setLights = useHouseDispatch();
    return (
        <Switch onClick={() => setLights(false)} />    
    )
}

context............

const MasterSwitch = () => {
    const setLights = useHouseDispatch();
    return (
        <Switch onClick={() => setLights(false)} />    
    )
}
//index.js
import createProvider from 'simple-stateful-provider';
const [
    DemoProvider,
    useDemoState,
    useDemoSetState
] = createProvider();

//app.js
return (
    <DemoProvider>
        <App/>
    </DemoProvider>
)
//component.js
const ExampleSet = () => {
    const state = useDemoState();
    const setState = useDemoSetState();

    return (
        <p>
            <input
                value={state || ''}
                onChange={evt => {
                    setState(evt.target.value)
                }}
            />
        </p>
    )
}