Issue
i want to fix the error "cannot invoke an object which can possibly be undefined" using react and typescript.
what i am trying to do? I am using usecontext react hook and creating a variable from it (dialogContext) in the components (home, Dialog and books component). In doing so i get the above mentioned error.
I am defining DialogContext in helper file like below
interface ContextProps {
setDialogOpen?: (open: boolean) => void;
}
export const DialogContext = React.createContext<ContextProps>({});
And importing DialogContext in components where needed that is (Main, home, Dialog components)
function MainComponent() {
let [showDialog, setShowDialog] = React.useState(false);
return (
<DialogContext.Provider
value={{
setDialogOpen: (open: boolean) => {
if (open) {
const sessionDialogClosed = sessionStorage.getItem('dialog');
if (sessionDialogClosed !== 'closed') {
setShowDialog(open);
sessionStorage.setItem('dialog', 'closed');
}
} else {
setShowDialog(open);
}
},
}}
>
{showDialog && <Dialog DialogContext={DialogContext}/>
<Route
path="/items">
<Home />
</Route>
<Route
path="/id/item_id">
<Books/>
</Route>
</DialogContext.Provider>
)
}
function Home() {
const dialogContext= React.useContext(DialogContext);
const handleClick = () {
dialogContext.setDialogOpen(true); //get error here
}
return (
<button onClick={handleClick}>add</button>
)
}
function Books({DialogContext} : Props) {
const dialogContext= React.useContext(DialogContext);
const handleClick = () {
dialogContext.setDialogOpen(true); //get error here
}
return (
<button onClick={handleClick()}>Click me</button>
)
}
function Dialog() {
return(
<div>
//sometext
<button onClick={dialogContext.setDialogOpen(false)}> hide</button> //get errror here
</div>
)
}
What i have tried?
I have added a check for undefined where dialogContext is used in components (Books, Home, Dialog) like for example in Books components i used like below,
function Books({DialogContext} : Props) {
const dialogContext= React.useContext(DialogContext);
const handleClick = () {
if (dialogContext !== 'undefined') {
dialogContext.setDialogOpen(true); //get error here
}
}
return (
<button onClick={handleClick()}>Click me</button>
)
}
But still the error "cannot invoke an object which can possibly be undefined" throws.
Could someone help me fix this error. thanks.
Edit:
I have tried to do below and it removes the error
function Books({DialogContext} : Props) {
const dialogContext= React.useContext(DialogContext);
const handleClick = () {
if (dialogContext && dialogContext.setDialogOpen) {
dialogContext.setDialogOpen(true);
}
}
return (
<button onClick={handleClick()}>Click me</button>
)
}
But instead of adding a check like this in every component what change should i make in the DialogContext helper file or what needs to be changed to fix keep checking for undefined or not. thanks.
Solution
You have a lot of typing mistakes in your code , I've edited the answer based on your comments and here is the final result. you can also see how it's work in codesandbox just click here to see.
and here is All of your code + a some fixes + a little change in structure
import * as React from "react";
import { Route, Switch, BrowserRouter as Router } from "react-router-dom";
interface ContextProps {
setShowDialog: (open: boolean) => void;
}
const DialogContext = React.createContext<ContextProps>({
setShowDialog: (open: boolean) => {}
});
function Home() {
const dialogContext = React.useContext(DialogContext);
const handleClick = () => {
dialogContext.setShowDialog(true); //It's Ok
};
return <button onClick={handleClick}>add</button>;
}
function Books() {
const dialogContext = React.useContext(DialogContext);
const handleClick = () => {
dialogContext.setShowDialog(true); //get error here
};
return <button onClick={handleClick}>Click me</button>;
}
function Dialog() {
const dialogContext = React.useContext(DialogContext);
const handleClick = () => {
dialogContext.setShowDialog(false);
};
return (
<div>
<button onClick={handleClick}> hide</button>
</div>
);
}
export default function MainComponent() {
const [showDialog, setShowDialog] = React.useState(false);
return (
<DialogContext.Provider
value={{
setShowDialog
}}
>
{showDialog && <Dialog />}
<Router>
<Switch>
<Route path="/">
<Home />
</Route>
<Route path="/books">
<Books />
</Route>
</Switch>
</Router>
</DialogContext.Provider>
);
}
Answered By - Taghi Khavari
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.