Home > OS >  How to implement jsx implementation of react context in tsx
How to implement jsx implementation of react context in tsx

Time:09-19

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.

CodePudding user response:

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>
  );
};
  • Related