首页 > 解决方案 > 如何在使用 useEffect 卸载时将状态设置为 false?

问题描述

我想在对话框组件卸载时将 isOpen 的状态切换为 false。

我想做什么?

我正在使用上下文切换对话框的状态。最初状态 isOpen 设置为 false。单击添加按钮时,状态 isOpen 为 true,单击取消按钮会将状态 isOpen 设置为 false。

现在,当用户不单击取消按钮时,即使用户导航到另一个页面,状态 isOpen 仍然为真。

下面是我的代码,

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

在上面的代码中,我使用 useeffect 和 return 关闭了卸载对话框。但是,如果用户单击调用句柄文件选择的输入按钮,这也会关闭对话框。

有人可以告诉我为什么即使没有卸载组件也会调用useeffect。

有人可以帮我解决这个问题吗?谢谢。

编辑:

我试过什么?

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

react useeffect 缺少依赖项 toggleDialog。要么包含它,要么删除依赖数组

但是当我把它改成这样

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

没有按预期工作。

标签: javascriptreactjs

解决方案


不确定您要达到的目标的全部范围,但您可以做这样的事情。因为这会在单击时切换对话框。

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

推荐阅读