如何使模式对话框的内容在打开时仅呈现一次?



我以前使用过材质UI,似乎没有遇到这个问题。问题是:当我使用脉轮ui模态对话框时,当它打开时,里面的所有组件都会渲染两次。我尝试禁用动画motionPreset={'none'},但没有帮助。

这是我的代码:

import "./styles.css";
import { useEffect } from "react";
import {
Box,
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
useDisclosure
} from "@chakra-ui/react";
const TestAppear = () => {
useEffect(() => {
console.log("TestAppear mounted");
}, []);
return <Box>Appear</Box>;
};
export default function App() {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose} motionPreset={"none"}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<TestAppear />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
<Button variant="ghost">Secondary Action</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
);
}

TestAppear组件清楚地显示了问题。如果您查看控制台,您会看到当对话框打开时,它会被渲染两次。

codesandbox 的代码示例

我正在做一个停车场的项目。当您点击停车位时,会弹出一个对话框,显示预订的时段。间隔列表是一个单独的组件,在其中从服务器加载间隔。因此,如果这个带有间隔列表的组件被挂载两次,那么请求将被发送到服务器两次,这是非常糟糕的。

正如Jacob所说,这种行为是由于严格的反应模式造成的。如果您转到渲染根的index.js文件,您可以看到元素被包裹在<React.SctMode>。这个包装器是您在具有空依赖数组的useEffect中所做的一切都被调用两次的原因。您可以简单地删除这个严格的模式包装器,并查看其区别。

最新更新