仅在 Material UI 对话框打开时触发 UseEffect()

Only trigger UseEffect() in Material UI Dialog when it is in opened

我有一个包含 Material UI 对话框(子)的父组件。现在这个对话框的目的是从 REST API.

获取和显示数据

目前,这是通过在 Dialog 组件中实现 UseEffect() 来实现的。但是,一旦安装了父组件,子组件内的 UseEffect() 就会启动。问题是我将丢失应该从父组件传递给子组件本身的信息(因为这两个组件都已安装同时)。

现在让我想到的是,我希望只有在单击显示它的按钮时才安装此对话框。这可能吗?

这是片段:

Parent.js

    const Parent = React.forwardRef((props, ref) => {

            const [openChildDialog, setOpenChildDialog] = useState(false)
    
        useEffect(() => {
// function here. This also going to set value in a state that will be used for the child component
        })

        const handleOpenChildDialog = () => {
            setOpenChildDialog(true)
        }
        const handleCloseChildDialog = () => {
            setOpenChildDialog(false)
        }
        
            return (
                <Page>
                    <PageTitle>
                        Parent Component Test
                    </PageTitle>

                // Dialog will only be mounted when this button is clicked.
                <Button onClick={handleOpenChildDialog}> Open the child dialog! </Button>
    
                    <ChildDialog
                        open={openChildDialog}
                        onClose={handleCloseChildDialog}
                    />
                </Page>
            )
        })

如果我的要求不可行,那么我愿意接受替代方案,只要子对话框组件内的 UseEffect() 不会在父组件安装时立即执行。

UseEffect() 的行为使其在安装、更新和卸载组件时执行。但是我在这里看到的解决方案是在 openChildDialog 更改为 true

时使用条件渲染子组件
{ openChildDialog &&
    <ChildDialog
        open={handleOpenChildDialog}
        onClose={handleCloseChildDialog}
    />

}

我给你留下了这个令人难以置信的指南,这样你就可以深入了解如何使用这个钩子:https://overreacted.io/a-complete-guide-to-useeffect/

要仅在打开时呈现 ChildDialog 组件,只需将其包装在条件中即可:

{ openChildDialog && (
  <ChildDialog
    open={openChildDialog}
    onClose={handleCloseChildDialog}
  />
)}

就您的 useEffect 而言 - 您可以包含一个数组作为 useEffect 的第二个参数,然后该函数将仅在数组中的任何内容发生变化时 运行,例如:

useEffect(() => {
  // this will run whenever any state or prop changes, as you haven't supplied a second parameter
})

useEffect(() => {
  // this will now only run when openChildDialog changes
  // you can easily put a check in here to see if openChildDialog is true to only run on open
}, [openChildDialog])

useEffect(() => {
  // an empty array means this will only run when the component is first mounted
}, [])

所以要回答您的 useEffect-inside-child 运行ning 错误,您可以这样做:

useEffect(() => {
 if (open) {
   // do stuff only when the open prop changes to true here
 }
}, [open])