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