someuser2491
someuser2491

Reputation: 1968

How to use context within same component file using react and typescript?

I want to access the state from one component to another. To do so i want to wrap contextprovider only to the component where state changes on clicking a button and return state from a usehook so that another component can access the state.

below is how the componnet looks without context applied,

function UploadButton () { //this is where state is set
    const [isDialogOpen, setIsDialogOpen] = React.useState(false); 
     
    const handleClick = () => {
        setIsDialogOpen(!isDialogOpen);
    }
    return (
        <>
            <Button onClick={handleClick}/>
            {isDialogOpen && <Upload/>}
        </>
    ); 
}

function UserButton() { //this is where state is accessed
    return (
        <Icon/> //this icon should be displayed only if !isDialogOpen
    );
}

With context looks like below, I have DialogContext within same file where UploadButton is.

 interface DialogCtxState {
     isDialogOpen: boolean;
     setIsDialogOpen: React.Dispatch<React.SetStateAction<boolean>>;
 }

 const initialDialogState: DialogCtxState = {
     isDialogOpen: false,
     setIsDialogOpen: () => {},
 };

 const DialogContext = React.createContext<DialogCtxState>(
     initialDialogState  
 );

 export const DialogContextProvider: React.FC = ({ children }) => {
     const [isDialogOpen, setIsDialogOpen] = React.useState<boolean>(false); 

     return (
         <DialogContext.Provider
             value={{
                 isDialogOpen,
                 setIsDialogOpen,
             }}
         >
            {children}
         </DialogContext.Provider>
    );
}

function UploadButton () {
    const {isDialogOpen, setIsDialogOpen} = React.useContext(DialogContext);
     

    const handleClick = () => {
         setIsDialogOpen(!isDialogOpen);
         console.log('isDialogOpen', isDialogOpen) //prints false here.
    }

    return (
        <DialogContextProvider>
            <>
                <Button onClick={handleClick}/>
                {isDialogOpen && <Upload/>} //this doesnt render on clicking button as isDialogOpen 
                //is false
            </>
        </DialogContextProvider>
    );
}

The above snippet doesn't render the Upload component as isDialogOpen is always false no matter if I click the button.

I am not knowing what is wrong. could someone help me with this? thanks.

Upvotes: 1

Views: 5011

Answers (1)

Robert Cooper
Robert Cooper

Reputation: 2240

The issue is that you need to move your context provider one level higher in your react components in order to use useContext in you UploadButton component. You cannot place the context provider inside of UploadButton in order to use it's context. You need to move the provider into a parent component.

Here's a codesandbox demostrating it.

Upvotes: 5

Related Questions