如何在React Native中使用componentWillUnmount?

时间:2019-01-21 11:42:02

标签: reactjs react-native

public Type IdentifyCorrectType()
{
    var identifyingCondition = GetCorrectType();// returns 1,2,3...
    switch(identifyingCondition)
    {
        case 1:
            return typeof(MyType1);
        case 2:
            return typeof(MyType2);
        case 3:
            return typeof(MyType3);
        default:
            return null;
    }
}

如何使用componentWillUnmount,因为我在下面收到警告。 当我使用componentWillUnmount时,有什么方法可以将setState显示为true吗? Warning

4 个答案:

答案 0 :(得分:2)

您正在代码中混合了几件事。您正在使用await,但使用this.showPosts()时未调用await。您也不会像await那样将try/catch包裹在await中。

有两种方法可以解决在未安装的组件上设置状态的问题。尽管这是一种反模式,但最简单的方法是在componentDidMountcomponentWillUnmount中设置一个变量以跟踪组件的安装状态。

因此,让我们重构您的代码,使其更有意义

这就是您的componentDidMountcomponentWillUnmount现在的样子。

async componentDidMount () {
  this._isMounted = true;
  await this.showPosts();
}

componentWillUnmount () {
  this._isMounted = false;
}

更新showPosts,使其完全为async/await

showPosts = async () => {
  try {
    var userID = await AsyncStorage.getItem('userID');
    let response = await fetch(strings.baseUri + 'getPostWithUserID', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        'user_id': userID
      })
    });

    let responseJson = await response.json();
    if (this._isMounted) {
      this.setState({show: false});
    }
  } catch (err) {
    console.error(error);
  }
}

或者,如果我们使用您当前的showPosts实现,它将看起来像这样,但是解决了在try周围缺少try / catch的问题。

showPosts = async () => {
  try {
    var userID = await AsyncStorage.getItem('userID');

    fetch(strings.baseUri + 'getPostWithUserID', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        'user_id': userID
      })
    })
      .then((response) => response.json())
      .then((responseJson) => {
        if (this._isMounted) {
          this.setState({show: false}); // If I comment this line, then I don't get the warning.
        }
      })
      .catch((error) => {
        console.error(error);
      });
  } catch (err) {
    console.warn(err);
  }
}

另一种选择是一旦做出承诺就取消它们。本文以某种方式解释了如何进行https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

答案 1 :(得分:0)

您可以检查组件是否以这种方式安装,然后在异步函数中检查此变量,以查看是否仍然可以运行该函数或以其他方式取消该函数:

for s:keyword in ['parameter', 'token']
    execute printf('syntax match menhirDeclarationKeyword "\<%%%s\>"', s:keyword)
endfor

答案 2 :(得分:0)

您可以将一些内部组件对象属性用作-isComponentMounted,然后在异步操作回调期间对其进行检查。

答案 3 :(得分:0)

在componentDidMount中设置状态而不在构造函数中设置初始状态不是一个好主意,因为它会触发额外的渲染,这可能会导致性能问题。

摘自官方文档:

  

您可以立即在componentDidMount()中调用setState()。它会触发额外的渲染,但是会在浏览器更新屏幕之前发生。这样可以保证即使在这种情况下render()将被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它经常会导致性能问题。在大多数情况下,您应该可以改为在Constructor()中分配初始状态。但是,对于模态和工具提示之类的情况,当您需要在渲染取决于其大小或位置的对象之前测量DOM节点时,这是必要的。

https://reactjs.org/docs/react-component.html#componentdidmount

但这又回到了为什么要使用componentWillUnmount吗?那是用于注销事件,推送通知,清理资源。