1

I'm using the second answer of this post to implement a React context that can be updated from a child component. This is my code so far:

app/authContext/index.tsx

import React, { useState } from "react";

export const AuthContext = React.createContext({
  auth: {user: null},
  setAuth: () => {}
})

export const AuthContextProvider = (props: any) => {

  const setAuth= (auth: any) => {
    setState({...state, auth: auth})
  }

  const initState = {
    auth: {user: null},
    setAuth: setAuth
  } 

  const [state, setState] = useState(initState)

  return (
    <AuthContext.Provider value={state}>
      {props.children}
    </AuthContext.Provider>
  )
}

app/index.tsx

import React, { useState } from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { Routes, Route } from "react-router-dom";

import './App.css';
import {mayan} from "./themes/mayan";
import AppHeader from './appHeader';

import { AuthContextProvider } from "./authContext";

import Home from "./Routes/home";
import Login from "./Routes/login";

function App() {
  return (
    <ThemeProvider theme={mayan}>
      <AuthContextProvider>
        <div className="App">
          <AppHeader />
          <header className="App-body">
            <Routes>
              <Route path="/" element={<Home />} />
              <Route path="login" element={<Login />} />
            </Routes>
          </header>
        </div>
      </AuthContextProvider>
    </ThemeProvider>
  );
}

export default App;

The problem is that I'm getting this error:

TS2322: Type '{ auth: { user: null; }; setAuth: (auth: any) => void; }' is not assignable to type '{ auth: { user: null; }; setAuth: () => void; }'.
  Types of property 'setAuth' are incompatible.
    Type '(auth: any) => void' is not assignable to type '() => void'.
    20 |
    21 |   return (
  > 22 |     <AuthContext.Provider value={state}>
       |                           ^^^^^
    23 |       {props.children}
    24 |     </AuthContext.Provider>
    25 |   )

I suppose this error raises because I'm using TypeScript instead of JavaScript, but I can't find how to solve it.

1 Answer 1

1

You have declared the context value to be an object with a setAuth function taking no arguments:

{
  auth: { user: null },
  setAuth: () => {}
}

But are passing a setAuth function that takes an argument:

const setAuth = (auth: any) => {
  setState({ ...state, auth })
}

Fix the context default value to match what you want to pass:

{
  auth: { user: null },
  setAuth: (auth: any) => {}
}

export const AuthContext = React.createContext({
  auth: { user: null },
  setAuth: (auth: any) => {}
});

Since you are using Typescript you might want to tighten up the declaration where you can, i.e. declare an Auth interface so that auth isn't just any.

Example:

interface Auth {
  user: string | null;
}

export const AuthContext = React.createContext({
  auth: { user: null },
  setAuth: (auth: Auth) => {}
})

export const AuthContextProvider = (props: any) => {
  const setAuth = (auth: any) => {
    setState({...state, auth: auth})
  }

  const initState = {
    auth: { user: null },
    setAuth
  };

  const [state, setState] = useState(initState);

  return (
    <AuthContext.Provider value={state}>
      {props.children}
    </AuthContext.Provider>
  );
};
Sign up to request clarification or add additional context in comments.

Comments

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.