5

I have set some dynamic styles and everything works just fine except when component is unmounted. Then it throws an error: Can't call setState (or forceUpdate) on an unmounted component.

It is the second screen in stack navigator, when I go to third, everything is fine, but when i go to first and component is unmounted it throws an error.

I have tried to remove event listener in componentWillUnmount but unsuccessfully, apparently I am doing something wrong.

Also, I have tried with this approach this.props.navigation.isFocused() and again it works just fine, but then if I am on the third screen and rotate the device and go back, Dimensions event listener do not see change and styling is a mess.

So how can I stop event listener when component is unmounted?

Thanks in advance.

constructor(props) {
    super(props);
    Dimensions.addEventListener("change", dims => {
      // this.props.navigation.isFocused() ?
      this.setState({
        resStyles: {
          imageFlex: Dimensions.get("window").height > 500 ? "column" : "row",
          imageHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
          infoHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
          infoWidth: Dimensions.get("window").height > 500 ? "100%" : "50%"
        }
      });
      // : null;
    });
  }

componentWillUnmount

componentWillUnmount() {
    console.log("Unmounted");

    Dimensions.removeEventListener("change", dims => {
      // this.props.navigation.isFocused() ?
      this.setState({
        resStyles: {
          imageFlex: Dimensions.get("window").height > 500 ? "column" : "row",
          imageHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
          infoHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
          infoWidth: Dimensions.get("window").height > 500 ? "100%" : "50%"
        }
      });
      // : null;
    });
  }
FatBoyGebajzla
  • 159
  • 1
  • 2
  • 10

2 Answers2

8

you should make a named function (Methode to be precise) like this

fun_name(){
      // this.props.navigation.isFocused() ?
  this.setState({
    resStyles: {
      imageFlex: Dimensions.get("window").height > 500 ? "column" : "row",
      imageHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
      infoHeight: Dimensions.get("window").height > 500 ? "50%" : "100%",
      infoWidth: Dimensions.get("window").height > 500 ? "100%" : "50%"
    }
  });
  // : null;
}

constructor(props) {
    super(props);
    Dimensions.addEventListener("change", this.fun_name);
  }

componentWillUnmount() {
    console.log("Unmounted");

    Dimensions.removeEventListener("change", this.fun_name);
  }

PS: don't forget to bind the function

evgeni fotia
  • 4,650
  • 3
  • 16
  • 34
  • Bravo!That is what I needed! This actually solves my problem! Thanks a lot evgeni fotia!!! But I still do not get it completely... Your code is pretty much the same as mine... Why then my code do not work and yours does? Tnx again. – FatBoyGebajzla Oct 10 '18 at 16:04
  • 1
    @FatBoyGebajzla check here https://www.w3schools.com/jsref/met_element_removeeventlistener.asp read the note in "Definition and Usage" and you will understand – evgeni fotia Oct 10 '18 at 16:09
  • Thank you, I did not know that. – FatBoyGebajzla Oct 10 '18 at 16:11
3

Define a function separately, to add/remove the listener to that specific function. also add listeners once the component has been mounted to avoid set state on an unmounted component

componentDidMount () {
    Dimensions.addEventListener('change', updateDimensions)
}
componentWillUnmount() {
    Dimensions.removeEventListener('change', updateDimensions)
}
updateDimensions() {
  this.props.navigation.isFocused() ?
  this.setState({
    resStyles: {
      imageFlex: Dimensions.get('window').height > 500 ? 'column' : 'row',
      imageHeight: Dimensions.get('window').height > 500 ? '50%' : '100%',
      infoHeight: Dimensions.get('window').height > 500 ? '50%" : '100%',
      infoWidth: Dimensions.get('window').height > 500 ? '100%' : '50%'
    }
  });
  : null;
}
Jesús
  • 41
  • 4