0
votes

When fetching data I'm getting:

Can't perform a React state update on an unmounted component.

The app still works, but react is suggesting I might be causing a memory leak.

I've searched a lot for a solution to this warning and made many changes (including using an isMounted state and an abortController) but haven't found anything which fixes this for me as of yet. This is due to the fact that I want to the output of the API to be a variable or constant so that I can use it in another class.

componentDidMount() {
  fetch("https://jirareportsforsolutions.azurewebsites.net/boards")
  .then(response => response.json())
  .then(
    (result) => this.setState(boards = JSON.parse(JSON.stringify(result, null, 2).slice(82, -1)))
  )
  // console.log(boards)
}
componentDidUpdate() {
  if (this.state.selectValues.length > 0) 
    fetch("https://jirareportsforsolutions.azurewebsites.net/sprints/" + boardId)
    .then(response => response.json())
    .then(
      (result) => this.setState(sprints = JSON.parse(JSON.stringify(result, null, 2).slice(68, -1)))
    )
    // console.log(sprints)
  }
}

This is the render component where 'boards' is being used within a dropdown (using the react-dropdown-select package) and 'sprints' is being passed to a different class(StartSprintDropdown):

render() {
  if (boards == null) {
    noData = "No boards available"
  } 
  return (
    <div>
      <div className="boardDropdown">
        <StyledSelect
          placeholder="Select a board"
          color={this.state.color}
          searchBy={this.state.searchBy}
          clearable={this.state.clearable}
          searchable={this.state.searchable}
          dropdownHandle={this.state.handle}
          dropdownHeight={this.state.dropdownHeight}
          direction={this.state.direction}
          labelField={this.state.labelField}
          valueField={this.state.valueField}
          options={boards}
          dropdownGap={this.state.gap}
          keepSelectedInList={this.state.keepSelectedInList}
          onChange={values => this.setValues(values)}
          noDataLabel={noData}
          closeOnSelect={this.state.closeOnSelect}
          dropdownPosition={this.state.dropdownPosition}
        />
      </div>
      <div>
        <StartSprintDropdown sprints={sprints} boardId={boardId} projectId={projectId} sprintError={sprintError}/>
      </div>
    </div>
  );}
}

This is the full warning that is shown:

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 the componentWillUnmount method.

I'm not sure if I have assigned the 'boards' and 'sprints variables correctly as they are not states but the app works fine, although the second fetch (within the componentDidUpdate) constantly fetches once triggered.

Since I'm new to React any help with this and my code is greatly appreciated.

1

1 Answers

0
votes

This could be happening because somewhere along the line, your component is getting destroyed, then the async call to this.setState gets run and prints this error message.

Try adding this to your class to see if your component is being destroyed too early:

componentWillUnmount() {
  console.log('unmounting!!!!')
}