0
votes

I'm using Redux to manage a global Dialog component. I pass the children components to the Dialog component using Redux actions.

A functional example is in this codesandbox: https://codesandbox.io/s/suspicious-keldysh-uuolb?file=/src/App.js

There is no problem opening the Dialog and rendering its children, the problem is when I try to pass a state with one of its children:

const handleOpenDialog = () => {
    dispatch(
      openDialog({
        title: <DialogTitle />,
        content: (
          <DialogContent
            form={form}
            setForm={setForm}
            setSubject={setSubject}
            subject={subject}
          />
        ),
        actions: <DialogActions form={form} />
      })
    );
  };

The Dialog renders fine, but I can't update the state of the props I passed to the Dialog. The component that calls the function to open the Dialog is this one:

export default function ContactSupport() {
  const dispatch = useDispatch();
  const [form, setForm] = useState("");
  const [subject, setSubject] = useState("");

  const handleOpenDialog = () => {
    dispatch(
      openDialog({
        title: <DialogTitle />,
        content: (
          <DialogContent
            form={form}
            setForm={setForm}
            setSubject={setSubject}
            subject={subject}
          />
        ),
        actions: <DialogActions form={form} />
      })
    );
  };

  return (
    <Paper onClick={handleOpenDialog}>
      <Grid container spacing={2}>
        <Grid item xs={12} container justify="center">
          <Typography>Icon</Typography>
        </Grid>
        <Grid item xs={12}>
          <Typography align="center">Contact support</Typography>
        </Grid>
      </Grid>
    </Paper>
  );
}

My intention is that when I click on this component, the Dialog is rendered with the state which is in this component. I need the state in this component, because I need to access it in the DialogActions component as well, because this component will call the API with the action.

In Firefox an error is shown in the console:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

I'm not sure why this component is unmounted, if it still shows in the Dialog background.

Any help to solve this issue, even with another design pattern for this, is appreciated.

Thank you

2

2 Answers

0
votes

A simple workaround I use when I don't want to search for the cause of re-rendering is defining a this._mounted=false in constructor, setting it to true in componentDidMount() and back to false in componentWillUnmount().

Now you use setState like so:

if (this._mounted) this.setState({...});

It's a version for a class component, but I hope you'd know how to use it in FC.

0
votes

Anyone with same case as mine, I solved it using a state action to set the component state in redux.

This way I have access thru the whole application, then I don't need to pass the state by props. The downside is that I'll have to remount the component every keystroke.

I updated the codesandbox with the solution I used.