在componentDidMount内部的回调中设置状态

时间:2018-04-20 12:46:54

标签: reactjs react-native

我目前正在使用React 16.3(React Native),编写here,它表明我应该在componentDidMount中而不是componentWillMount中进行任何异步请求,因为这样做很快就被弃用了。

不幸的是,我正在尝试获取无操作警告,因为我试图在componentDidMount中获取数据,将我的axios请求返回的数据设置为我的状态。

这是一个片段 -

Region

和警告 -

export default class MyComponent extends Component {
    state = {
      myData: []
    }

    componentDidMount() {
      axios.get('api-endpoint')
      .then(res => this.setState({ myData: res.data })
    }
    render() { return <View>...</View> }
}

3 个答案:

答案 0 :(得分:4)

这就是在组件中使用异步代码的问题。例如,当Promise解析时(可能需要几秒钟),用户可能已经导航到应用程序的另一部分,因此当Promise解析并尝试执行setState时 - 您会收到尝试更新未安装组件的错误。

我的建议是为你的异步逻辑使用像redux-thunk,redux-saga或redux-observable等......但是,你可以做一个简单的检查 - 但它是一个反模式

export default class MyComponent extends Component {
    state = {
      myData: []
    }

    componentDidMount() {
      this.isMounted = true;

      axios.get('api-endpoint')
      .then(res => {
        if(this.isMounted) {
          this.setState({ myData: res.data })
        }
      })
    }

    componentWillUnmount() {
      this.isMounted = false;
    }
    render() { return <div>...</div> }
}

答案 1 :(得分:1)

我的建议是遵循适当的Flux。您可以在MyComponent中为componentDidMount()附加商店收件人,如下所示。

componentDidMount() {
   //call async data fecthing method here
   store.addListener('eventname', onDataReceipt);
}

在此之前,您可以将状态更改逻辑移至onDataReceipt方法。从componentDidMount()dispatch调用异步数据获取商店已注册的操作。然后从商店发出事件。由于您已经在componentDidMount()订阅了该活动,因此将会执行事件发送onDataReceipt()。 也不要忘记在componentWillUnMout()

中删除监听器
componentWillUnMount() {
   store.removeListener('eventname', onDataReceipt);
}

Flux将照顾其余的并且你不会&#39;担心警告。

答案 2 :(得分:1)

更新 - 我的组件被卸载的原因是因为我在父组件中设置了状态。当在父组件中设置状态时,它强制重新呈现组件,该组件沿着树&amp;在异步请求中间卸载。