1

I am trying to implement Contexts in my React project. Every time I have tried implementing this Context, I get the same error:

Property 'state' does not exist on type '{ count: number; currentColor: string; }'.

  > 40 |   let { state, dispatch } = React.useContext(ContextOne);
       |         ^

Context Provider code:

import * as React from "react";

let ContextOne = React.createContext(initialState);

let initialState = {
  count: 10,
  currentColor: "#bada55"
};

let reducer = (state, action) => {
  switch (action.type) {
    case "reset":
      return initialState;
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "set-color":
      return { ...state, currentColor: action.payload };
  }
};

function ContextOneProvider(props) {
  let [state, dispatch] = React.useReducer(reducer, initialState);
  let value = { state, dispatch };


  return (
    <ContextOne.Provider value={value}>{props.children}</ContextOne.Provider>
  );
}

let ContextOneConsumer = ContextOne.Consumer;

export { ContextOne, ContextOneProvider, ContextOneConsumer };

I have tried numerous online example Context Providers, but every time useContext() is called, the same error appears. What needs to be modified to get the Context working?

------------------------------------------Edit------------------------------------------

Thanks to soywood, here is the working Context Provider code:

import * as React from "react";

type State = {
  count: number
  currentColor: string
}

const initialState: State = {
  count: 10,
  currentColor: "#bada55",
};

type Context = {
  state: State
  dispatch: React.Dispatch<Action>
}

type Action = {
  type: string,
  payload: string
}
const ContextOne = React.createContext<Context>({
  state: initialState,
  dispatch: () => {},
});

// You need to define the type Action
const reducer: React.Reducer<State, Action> = (state, action) => {
  switch (action.type) {
    case "reset":
      return initialState;
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "set-color":
      return { ...state, currentColor: action.payload };
  }
};

function ContextOneProvider(props) {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  const value: Context = { state, dispatch };

  return (
    <ContextOne.Provider value={value}>{props.children} </ContextOne.Provider>
  );
}

let ContextOneConsumer = ContextOne.Consumer;

export { ContextOne, ContextOneProvider, ContextOneConsumer };

2 Answers 2

2

The createContext parameter type should match your ContextOne.Provider value type. You also need to improve your types to guide more the TypeScript compiler:

import * as React from "react";

type State = {
  count: number
  currentColor: string
}

const initialState: State = {
  count: 10,
  currentColor: "#bada55",
};

type Context = {
  state: State
  dispatch: React.Dispatch<State>
}

const ContextOne = React.createContext<Context>({
  state: initialState,
  dispatch: () => {},
});

// You need to define the type Action
const reducer: React.Reducer<State, Action> = (state, action) => {
  switch (action.type) {
    case "reset":
      return initialState;
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "set-color":
      return { ...state, currentColor: action.payload };
  }
};

function ContextOneProvider(props) {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  const value: Context = { state, dispatch };

  return (
    <ContextOne.Provider value={value}>{props.children} </ContextOne.Provider>
  );
}

let ContextOneConsumer = ContextOne.Consumer;

export { ContextOne, ContextOneProvider, ContextOneConsumer };
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for your answer. After making that change, I'm getting a different error. "Property 'disptach' is missing in type '{ state: any; dispatch: React.Dispatch<any>; }' but required in type '{ state: { count: number; currentColor: string; }; disptach: () => void; }'." Which I am getting when setting the Provider value "<ContextOne.Provider value={value}>{props.children}</ContextOne.Provider>".
Sorry, I made a typo disptach instead of dispatch... I update my answer.
No worries, thank you for all the help. The error that appears now is "Type '{ state: any; dispatch: React.Dispatch<any>; }' is not assignable to type '{ state: { count: number; currentColor: string; }; dispatch: () => void; }'. Types of property 'dispatch' are incompatible. Type 'Dispatch<any>' is not assignable to type '() => void'.". I tried changing the initialState declaration to "dispatch: React.Dispatch<any>", but it tells me "'(' expected.".
Do you use plain JavaScript or TypeScript ?
I'm using TypeScript.
|
0

Your issue is that you're providing an initial state to your context provider which has the properties count and currentColor, while the value (the new state) you provide in ContextOneProvider has the properties state and dispatch.

I imagine you'll want to swap initialState to be something along the lines of:

{
  state: null,
  dispatch: null,
}

If you're using typescript you may want to provide an interface that has those as optional params.

1 Comment

Thank you for your answer. After making those changes, I get an error that says "Type '{ state: any; dispatch: Dispatch<any>; }' is missing the following properties from type '{ count: number; currentColor: string; }': count, currentColor", which I am getting when setting the Provider value at "Which I am getting when setting the Provider value "<ContextOne.Provider value={value}>{props.children}</ContextOne.Provider>"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.