简体   繁体   中英

How to set state to false on unmount using useeffect?

i want to toggle state of isOpen to false on dialog component unmount.

what i am trying to do?

i am toggling state of a dialog using context. initially the state isOpen is set to false. when add button is clicked the state isOpen is true and clicking cancel button will set state isOpen to false.

now when user doesnt click cancel button then the state isOpen is true still even when user navigates to another page.

below is my code,

function Main() {
    return(
        <DialogContextProvider>
            <Parent/>
        </DialogContextProvider>
    );
}


function Parent() {
    return (
        <AddButton/>
    );
}


function AddButton() {
    const { isOpen, toggleDialog } = useDialogs();
    return(
        <Icon 
            onClick={() => {
                toggleDialog(true); //isOpen set to true
            }}/>
        {isOpen &&
            <Dialog
                onCancel={() => {
                toggleDialog(false); //isOpen set to false
        }}
    );
}


function Dialog() {
    useEffect(() => {
        return () => {
            toggleDialog(false);
        };
    });
 
    handlefileselection = () => {
        //some logic to upload files
    }

    return (
        <input type='file' onChange={handlefileselection}/> //on clicking this the isOpen state is 
        //set to false
    );
}




interface DialogsState {
    isOpen: boolean;
    setOpen: React.Dispatch<React.SetStateAction<boolean>>;
}

const initialState: DialogsState = {
    isOpen: false,
    setIsOpen: () => {},
};

const DialogsContext = React.createContext<DialogsState>(
    initialState
);

export const DialogsContextProvider: React.FC = ({ children }) => {
    const [isOpen, setOpen] = React.useState<boolean>(false);

    return (
        <DialogsContext.Provider
            value={{isOpen,setOpen}}>
            {children}
        </DialogsContext.Provider>
    );
};


export function useDialogs() {
    const {
        isOpen,
        setOpen,
    } = React.useContext(ScheduleDialogsContext);
    const toggleDialog = (toggleValue: boolean) => {
        setOpen(toggleValue);
    };

    return {
        isOpen,
        toggleDialog,
    };
} 

In the above code, i close the dialog on unmount using useeffect with return. but this also closes the dialog if user clicks input button which invokes handlefileselection.

could someone tell me why the useeffect is invoked even though component is not unmounted.

could someone help me fix this? thanks.

Edit:

what i have tried?

useEffect(() => {
    return () => {
        toggleDialog(false);
    };
}, []); //error here

react useeffect has a missing dependency toggleDialog. either include it or remove the dependancy array

but when i change it to like this

useEffect(() => {
    return () => {
        toggleDialog(false);
    };
}, [toggleDialog]);

doesnot work as expected.

Not sure on the full scope of what you're trying to achieve but you can do something like this. As this toggles dialog when its clicked.

function AddButton() {
   const { isOpen, toggleDialog } = useDialogs(false);
   const toggleOpen = () => {
     toggleDialog(!isOpen); // will toggle from false to true, back and forth. 
   }
    return(
        <Icon 
            onClick={toggleOpen}/>
         {isOpen && (
            <Dialog
                onCancel={null} // this will longer be needed as onClick handles the toggling
               toggleDialog(false); // isOpen set to false
            />
          )
        }
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM