Skip to content

Instantly share code, notes, and snippets.

@just-boris
Created August 31, 2022 10:54
Show Gist options
  • Save just-boris/7c5f4474d3cc663c016d9662ae6a64c3 to your computer and use it in GitHub Desktop.
Save just-boris/7c5f4474d3cc663c016d9662ae6a64c3 to your computer and use it in GitHub Desktop.
import { createStateLifter } from './state-lifter'
const { Provider, useLiftedState } = createStateLifter("all");
export const LiftedCounter = () => (
<Provider>
<Filter />
<List />
</Provider>
);
const Filter = () => {
const [state, setState] = useLiftedState();
return (
<select value={state} onChange={(event) => setState(event.target.value)}>
<option value="all">All</option>
<option value="fruits">Fruits</option>
<option value="vegetables">Vegetables</option>
</select>
);
};
const List = () => {
const [state] = useLiftedState();
return (
<div>
<p>Displaying items for filter "{state}"</p>
{/*TODO: Actual items display*/}
</div>
);
};
import { ReactNode, createContext, useContext, useState, Dispatch, SetStateAction } from "react";
type StoreContext<T> = [state: T, setState: Dispatch<SetStateAction<T>>];
export default function createStateLifter<T>(initialState: T) {
const Context = createContext<StoreContext<T> | null>(null);
function useLiftedState() {
const value = useContext(Context);
if (!value) {
throw new Error("Provider not found");
}
return value;
}
function Provider({ children }: { children: ReactNode }) {
const state = useState(initialState);
return <Context.Provider value={state}>{children}</Context.Provider>;
}
return { useLiftedState, Provider };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment