1

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.

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks but it is not updating. everything seems fine but this doesnt work.
@someuser2491 updated my answer with what I think is the solution to your issue

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.