Skip to content Skip to sidebar Skip to footer

Cannot Flush Updates When React Is Already Rendering

I'm trying to show an alert when the API returns an error. For the alert window I'm using sweetalert2. In my render method I'm checking if the error message contains content. If it

Solution 1:

{saveLabelFetchError && this.toggleAlertFailure(saveLabelFetchError)}

You are trying to update the dom before render cycle i.e before component has mounted. hence, you are getting an error.

Ideally, you should avoid using any library that mutates dom directly (not via react APIs) with react lib. You can read more from here

The solution is to check if there is a change in props value, if so then show error popup. And also make sure we are not mutating dom during react's render cycle.

importReact, { Component } from"react";
importPropTypesfrom"prop-types";
import { connect } from"react-redux";
import { bindActionCreators } from"redux";

import { saveLabelValueRequest } from"../../actions/labels";

importSwalfrom"sweetalert2";
import"./styles.css";
importButtonfrom"@kof/button";

exportclassNewLabelsextendsComponent {
  state = {
    labelInput: "",
    prevSaveLabelFetchError: ""
  };

  staticgetDerivedStateFromProps(props, state) {
    if (props.saveLabelFetchError !== state.prevSaveLabelFetchError) {
      this.toggleAlertFailure(props.saveLabelFetchError);
      return {
        prevSaveLabelFetchError: props.saveLabelFetchError
      };
    }
    returnnull;
  }

  inputChangedhandler = e => {
    this.setState({ labelInput: e.target.value });
  };

  toggleAlertFailure = message => {
    Swal.fire({
      type: "error",
      title: "Oops...",
      text: message
    });
  };

  saveLabel = event => {
    event.persist();
    event.preventDefault();
    Swal.fire({
      title: "Are you sure?",
      text: "You won't be able to revert this!",
      type: "warning",
      showCancelButton: true,
      confirmButtonColor: "#3085d6",
      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, save it."
    }).then(result => {
      if (result.value) {
        const labelKeyUuid = this.props.labelKey.uuid;
        const labels = event.target.elements.labels.value;
        this.props.saveLabelValue(labelKeyUuid, labels);
      }
    });
  };

  render() {
    const { load } = this.props;
    return (
      <div><formonSubmit={this.saveLabel}><textareaonChange={this.inputChangedhandler}></textarea><textarea></textarea><ButtononClick={() => load(this.state.labelInput)}>Preview</Button><Buttontype="submit">Save</Button></form></div>
    );
  }
}

NewLabels.propTypes = {
  saveLabelFetchError: PropTypes.string,
  isFetching: PropTypes.bool,
  labelKey: PropTypes.object,
  saveLabelValue: PropTypes.func
};

NewLabels.defaultProps = {
  saveLabelFetchError: "",
  labelKey: {},
  isFetching: false,
  saveLabelValue: () => {}
};

exportdefaultconnect(
  state => ({
    saveLabelFetchError: state.labelsStore.saveLabelError,
    isFetching: state.labelsStore.isFetching,
    labelKey: state.labelsStore.labelKey
  }),
  dispatch =>bindActionCreators(
      {
        saveLabelValue: saveLabelValueRequest
      },
      dispatch
    )
)(NewLabels);


You can also look at react wrapper for sweetalert2

Solution 2:

Try this code snippet:

const [state, setState] = useState(true)

constrenderFunc = () => {
    ...
    setState(false)
}

state && renderFunc()

Post a Comment for "Cannot Flush Updates When React Is Already Rendering"