Home > Blockchain >  Building a UseContext Provider typeScript
Building a UseContext Provider typeScript

Time:10-10

Hi I'm building a UseContext Provider with typescript. I think I've build it correctly but I've got a litle type error but I can't figure it out.

type SetValue = (value: any) => void;
export interface AppContextInterface {
  value: any;
  setValue: SetValue;
}

export const ExempleCtx = createContext<AppContextInterface | null>(null);

const CtxProvider = ({ children }: { children: React.ReactNode }) => {
  const [value, setValue] = useState<any>(null);
  return (
    <ExempleCtx.Provider value={{ value, setValue }}>
      {children}
    </ExempleCtx.Provider>
  );
};
export default CtxProvider;

interface Test {
  username: any;
}

const defaultState = {
  username: "thomas",
};

export const AppContext = createContext<Test>(defaultState);

export function Hooktest() {
  return (
    <CtxProvider>
      <Btn></Btn>
    </CtxProvider>
  );
}

function Btn() {
  const { value, setValue } = useContext(ExempleCtx);
  return <div onClick={() => setValue("thomas")}>{value}</div>;
}

enter image description here

I tried typing the useState but it's not comming from their. I think its my createContext that is not correctly type. Thank you for your repplies.

CodePudding user response:

The problem is that ExempleCtx has type AppContextInterface | null and you cannot destructure from null.

If you are sure, just let TS know that useContext(ExempleCtx) will never return null. I think there is no way around it but you have to use type assertion. Use the as keyword.

  const { value, setValue } = useContext(ExempleCtx) as AppContextInterface;

If you do not want to fill your codebase with these then just create a seperate hook and return the val with non-null assertion operator. It tells TS that the value is non-null and non-undefined:

const useExempleCtx = () => {
  const val = useContext(ExempleCtx);
  return val!;
};
  const { value, setValue } = useExempleCtx();

Link

CodePudding user response:

When you first created the context export const ExempleCtx = createContext<AppContextInterface | null>(null);, you set his type to AppContextInterface | null. The context can be null.

To ignore this warning, you can just add a ! like so
const { value, setValue } = useContext(ExempleCtx!);

  • Related