marmelab / react-admin

A frontend Framework for building data-driven applications running on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.58k stars 5.21k forks source link

Passing a custom `Alert` component to `notify()` removes the whole app from the DOM #9841

Closed jstoeffler closed 1 week ago

jstoeffler commented 2 months ago

What you were expecting:

I have a custom mutationOptions with onError on a Create form that displays a custom Alert component:

      mutationOptions={{
        onError: () => {
          notify(<Alert severity="error">This is a custom error</Alert>);
        },
      }}

This works fine:

https://github.com/marmelab/react-admin/assets/3008836/e40066ec-a636-47c8-a98b-f9fe7cc1c963

I would expect to be able to extract this alert's JSX to do something like:

const CustomAlertComponent = () => {
  return <Alert severity="error">This is a custom error</Alert>;
};

//...

      mutationOptions={{
        onError: () => {
                notify(<CustomAlertComponent />);
         },
      }}

And it should work the same.

What happened instead:

I get a white page instead of seeing the error, it breaks the app and there is no error log:

https://github.com/marmelab/react-admin/assets/3008836/6685219b-ad5d-41c7-9d83-126c48129d1c

Steps to reproduce:

Related code:

import { Create, SimpleForm, TextInput, useNotify } from "react-admin";
import { Alert } from "@mui/material";

const CustomAlertComponent = () => {
  return <Alert severity="error">This is a custom error</Alert>;
};

export const PostCreate = () => {
  const notify = useNotify();
  return (
    <Create
      mutationOptions={{
        onError: () => {
          // This does not work (creates a blank page with no content):
          notify(<CustomAlertComponent />);
          // This works:
          // notify(<Alert severity="error">This is a custom error</Alert>);
        },
      }}
    >
      <SimpleForm>
        <TextInput source="title" />
        <TextInput source="body" />
      </SimpleForm>
    </Create>
  );
};
insert short code snippets here

Other information:

Environment

erwanMarmelab commented 2 months ago

Hello @jstoeffler,

Nice catch :+1:, reproduced in this Stackblitz (by clicking on the "click" button in the Post create page)

djhi commented 1 week ago

You have to wrap your component in a forwardRef:

const CustomAlertComponent = React.forwardRef((props, ref) => {
    return (
        <Alert ref={ref} severity="error">
            This is a custom error
        </Alert>
    );
});

This is required by Material UI