typical-coral
typical-coral3mo ago

useCustomModalForm

how to not close the form and invalidate on success and only invalidate when the form is closed manually.
14 Replies
kapa.ai
kapa.ai3mo ago
Hi @Joe Gaffney. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To achieve what you're asking with useCustomModalForm, you'll need to customize a few settings. Here's how you can prevent the form from closing automatically on success, while still invalidating queries when the form is closed manually: 1. Set autoSubmitClose to false to prevent the modal from closing automatically after a successful submit:
const modalForm = useModalForm({
modalProps: {
autoSubmitClose: false,
},
});
const modalForm = useModalForm({
modalProps: {
autoSubmitClose: false,
},
});
2. Use the invalidateOnClose property of the autoSave feature to invalidate queries when the modal is closed manually:
const modalForm = useModalForm({
autoSave: {
enabled: true,
invalidateOnClose: true,
},
});
const modalForm = useModalForm({
autoSave: {
enabled: true,
invalidateOnClose: true,
},
});
3. To handle the invalidation manually when closing the form, you can use the close function returned by useModalForm along with the useInvalidate hook:
import { useInvalidate } from "@refinedev/core";

const invalidate = useInvalidate();
const { close } = useModalForm();

const handleClose = () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
close();
};
import { useInvalidate } from "@refinedev/core";

const invalidate = useInvalidate();
const { close } = useModalForm();

const handleClose = () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
close();
};
By combining these approaches, you can keep the form open after a successful submission and only invalidate queries when the form is closed manually. Sources: useModalForm Properties (https://refine.dev/docs/packages/react-hook-form/use-modal-form/#properties) useModalForm Return Values (https://refine.dev/docs/packages/react-hook-form/use-modal-form/#return-values) useModalForm autoSave (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-modal-form/#autosave) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422289470487003153> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
typical-coral
typical-coralOP3mo ago
@kapa.ai can i overide the model from close to do this
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, you can override the modal's close behavior to implement custom logic, including query invalidation. Here's how you can do it: 1. First, you'll need to use the close function returned by useModalForm and combine it with your custom logic:
const { close: originalClose, ...rest } = useModalForm({
// other options
});
const { close: originalClose, ...rest } = useModalForm({
// other options
});
2. Then, you can create a custom close function that includes your invalidation logic:
import { useInvalidate } from "@refinedev/core";

const invalidate = useInvalidate();

const customClose = () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
originalClose();
};
import { useInvalidate } from "@refinedev/core";

const invalidate = useInvalidate();

const customClose = () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
originalClose();
};
3. Now, you can use this customClose function instead of the original close function:
return (
<Modal
{...rest.modalProps}
onCancel={customClose}
>
{/* Your form content */}
</Modal>
);
return (
<Modal
{...rest.modalProps}
onCancel={customClose}
>
{/* Your form content */}
</Modal>
);
By doing this, you're overriding the default close behavior of the modal to include your custom invalidation logic. This way, queries will only be invalidated when the form is closed manually, and not automatically after a successful submission. Remember to adjust the resource name and the query types you want to invalidate based on your specific use case. useModalForm Return Values (https://refine.dev/docs/packages/react-hook-form/use-modal-form/#return-values) Invalidation Guide (https://refine.dev/docs/guides-concepts/forms/#invalidation-) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422289470487003153> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
typical-coral
typical-coralOP3mo ago
@kapa.ai uis there another way to listen if the form is closed then invalidate
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, there is another way to listen for when the form is closed and then invalidate queries. You can use the onClose callback provided by the useModalForm hook. Here's how you can implement this approach: 1. First, import the necessary hooks:
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
2. Then, set up your useModalForm hook with an onClose callback:
const invalidate = useInvalidate();

const { modalProps, formProps } = useModalForm({
// other options
modalProps: {
onClose: () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
},
},
});
const invalidate = useInvalidate();

const { modalProps, formProps } = useModalForm({
// other options
modalProps: {
onClose: () => {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
},
},
});
In this setup, the onClose callback will be triggered whenever the modal is closed, either by clicking the close button, clicking outside the modal, or programmatically closing it. When this happens, it will run the invalidation logic. This approach has the advantage of being more declarative and doesn't require overriding the default close function. It also ensures that the invalidation happens regardless of how the modal is closed. Remember to replace "your-resource" with the actual resource name you're working with, and adjust the invalidates array to include the query types you want to invalidate. useModalForm Properties (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-modal-form/#properties) useInvalidate Hook (https://refine.dev/docs/data/hooks/use-invalidate/) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422289470487003153> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
typical-coral
typical-coralOP3mo ago
@kapa.ai modelProps does not support that
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize for the confusion in my previous response. You are correct that modalProps does not directly support an onClose callback as I suggested. Thank you for pointing that out. Let me provide a more accurate solution based on the available options in useModalForm. Instead of using modalProps.onClose, we can use the close function returned by useModalForm along with the React.useEffect hook to listen for changes in the modal's visibility. Here's how you can implement this:
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
import { useEffect } from "react";

const invalidate = useInvalidate();

const { modalProps, formProps, close, visible } = useModalForm({
// other options
});

useEffect(() => {
if (!visible) {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
}
}, [visible]);
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
import { useEffect } from "react";

const invalidate = useInvalidate();

const { modalProps, formProps, close, visible } = useModalForm({
// other options
});

useEffect(() => {
if (!visible) {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
}
}, [visible]);
In this approach, we're using the visible state returned by useModalForm to detect when the modal is closed. The useEffect hook will run whenever the visible state changes, and if it becomes false (indicating the modal has closed), it will trigger the invalidation. This method allows you to listen for the modal closing and perform the invalidation without overriding the default close behavior or relying on unsupported props. Remember to replace "your-resource" with your actual resource name and adjust the invalidates array as needed for your use case. useModalForm Return Values (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-modal-form/#return-values) useInvalidate Hook (https://refine.dev/docs/data/hooks/use-invalidate/) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422289470487003153> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
typical-coral
typical-coralOP3mo ago
@kapa.ai but then this will run on mount
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're absolutely right, and I apologize for overlooking that detail. You've made a very astute observation. The useEffect hook would indeed run on mount, which is not the desired behavior in this case. Let's refine our approach to avoid this issue. We can modify our solution to use a ref to track whether the component has mounted, ensuring we only invalidate when the modal is actually closed and not on the initial mount. Here's an improved version:
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
import { useEffect, useRef } from "react";

const invalidate = useInvalidate();

const { modalProps, formProps, visible } = useModalForm({
// other options
});

const isMounted = useRef(false);

useEffect(() => {
if (isMounted.current) {
if (!visible) {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
}
} else {
isMounted.current = true;
}
}, [visible]);
import { useModalForm } from "@refinedev/antd";
import { useInvalidate } from "@refinedev/core";
import { useEffect, useRef } from "react";

const invalidate = useInvalidate();

const { modalProps, formProps, visible } = useModalForm({
// other options
});

const isMounted = useRef(false);

useEffect(() => {
if (isMounted.current) {
if (!visible) {
invalidate({
resource: "your-resource",
invalidates: ["list", "many", "detail"],
});
}
} else {
isMounted.current = true;
}
}, [visible]);
In this updated version: 1. We use a useRef hook to create a mutable isMounted flag. 2. On the first render, isMounted.current is false, so we just set it to true and don't run the invalidation. 3. On subsequent renders, when visible changes and isMounted.current is true, we check if the modal has been closed (!visible) and only then run the invalidation. This approach ensures that the invalidation only occurs when the modal is actually closed, not on the initial mount or when it opens. useModalForm Return Values (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-modal-form/#return-values) useInvalidate Hook (https://refine.dev/docs/data/hooks/use-invalidate/) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422289470487003153> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?