title: Revert changes in MUI datagrid to original if the cell does not pass validation and then is clicked out of
body: <p>I currently have a MUI datagrid in which I am validating an email field. The validation works and it does revert back to the original but only if the escape key is pressed. To do this I modified the <a href="https://mui.com/x/react-data-grid/editing/#validation" rel="nofollow noreferrer">MUI validation</a> example that they give in which a tooltip will appear if the validation fails.</p>
  <p>I want it to revert back to the original if the validation fails and then the cell is clicked out of. I tried using onBlur and stopCellEditMode to accomplish this and clicking outside does now revert it back to the original. The new problem is that it reverts if the email is correct as well. If you remove handleBadEmail the email saves fine. Here is my code:</p>
  <pre><code>let promiseTimeout;
  const validateEmail = (email) =&gt; {
    return new Promise((resolve) =&gt; {
      promiseTimeout = setTimeout(() =&gt; {
        let emailWorks = false;
        if (
          //https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript
          String(email)
            .toLowerCase()
            .match(
              /^(([^&lt;&gt;()[\]\\.,;:\s@&quot;]+(\.[^&lt;&gt;()[\]\\.,;:\s@&quot;]+)*)|(&quot;.+&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
            )
        ) {
          emailWorks = true;
        }
        resolve(emailWorks ? null : `${email} is not a valid email.`);
      }, Math.random() * 500 + 100); // simulate network latency
    });
  };
  
  const StyledTooltip = styled(({ className, ...props }) =&gt; (
    &lt;Tooltip {...props} classes={{ popper: className }} /&gt;
  ))(({ theme }) =&gt; ({
    [`&amp; .${tooltipClasses.tooltip}`]: {
      backgroundColor: theme.palette.error.main,
      color: theme.palette.error.contrastText,
    },
  }));
  
  function NameEditInputCell(props) {
    
    const { error, value } = props;
    const apiRef = useGridApiContext();
  
    const handleBadEmail = async () =&gt; {
  
      let oldValue = apiRef.current.setEditCellValue({
        id: props.id,
        field: &quot;email&quot;,
        value: value,
      });
  
      if (error) {
       
        apiRef.current.stopCellEditMode({
          id: props.id,
          field: &quot;email&quot;,
          value: oldValue,
          ignoreModifications: false,
        });
      }
    };
  
    return (
      &lt;StyledTooltip open={!!error} title={error}&gt;
        &lt;GridEditInputCell onBlur={handleBadEmail} {...props} /&gt;
      &lt;/StyledTooltip&gt;
    );
  }
  
  function renderEditName(params) {
    return &lt;NameEditInputCell {...params} /&gt;;
  }
  
  
  const ColDefs = () =&gt; {
    const preProcessEditCellProps = async (params) =&gt; {
      const errorMessage = await validateEmail(params.props.value.toString());
      return { ...params.props, error: errorMessage };
    };
  
    return {
      columns: [
        {
          field: &quot;col1&quot;,
          headerName: &quot;Seller&quot;,
          flex: 1,
          editable: true,
        },
        {
          field: &quot;email&quot;,
          headerName: &quot;Email&quot;,
          flex: 1,
          editable: true,
          preProcessEditCellProps,
          renderEditCell: renderEditName,
        },
  </code></pre>