首页 > 解决方案 > React Native - componentDidUpdate 导致应用程序运行缓慢

问题描述

我遇到了这个问题,与其他组件应该作为componentDidMountComponentWillMount. 为了this.state在导航到另一个屏幕时更新自身,它需要componentDidUpdate获取数据。

constructor(props)
{

  super(props);

  this.state = {
  isLoading: true,
  username: '',
  dataSource: ''
};
AsyncStorage.getItem("username").then((value) => {
  this.setState({"username": value})
});
}
saveData(value){
    AsyncStorage.setItem("username", value);
    this.setState({"username": value});
}
componentDidUpdate() {


      return fetch(`http://www.example.com/React/user-profile.php?username=${this.state.username}` , {
       method: 'POST',
       headers: {
         'Accept': 'application/json',
         'Content-Type': 'application/json',
       }

      })
        .then((response) => response.json())
        .then((responseJson) => {
          this.setState({
            isLoading: false,
            dataSource: responseJson,
            },function() {
              // In this block you can do something with new state.
            });
        })
        .catch((error) => {
          console.error(error);
        });
    }

当我使用屏幕以外componentDidUpdate的其他组件时,不会显示任何内容,并且状态不会改变。是否有可以更新componentDidUpdate且不会导致性能问题的组件?另外需要注意的是,我使用componentDidMount的时候性能没有下降,但是状态没有改变。

 render() {


    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, paddingTop: 20}}>
          <ActivityIndicator />
        </View>
      );
    }


      return(

         <View style = { styles.MainContainer }>
         <ScrollView>

         <FlatList

           data={ this.state.images}

           ItemSeparatorComponent = {this.FlatListItemSeparator}


           renderItem={({item}) => <View>


           <RkCard style={{width:'75%', marginLeft: 50, marginBottom: 50, backgroundColor:'#f5f5f5'}}>
            <Lightbox>
             <FastImage rkCardImg source={{uri:`http://www.example.com/profiles/uploads/${item.images}`,
             headers:{ Authorization: 'someAuthToken' },
             priority: FastImage.priority.high,
              }}
               resizeMode={FastImage.resizeMode.contain}
               style={{width: '100%'}}/>
               </Lightbox>

             <View rkCardContent>
             <Makiko
                  label={'Comment'}
                  iconClass={FontAwesomeIcon}
                  iconName={'comment'}
                  iconColor={'white'}
                  inputStyle={{ color: '#db786d' }}
                />
             </View>
             <View rkCardFooter>

               <Text> {item.note}</Text>
             </View>
           </RkCard>


           </View>


         }

         keyExtractor={(item, index) => index.toString()}
         removeClippedSubviews

      />


         </ScrollView>
         </View>
       );
     }
   }

标签: react-native

解决方案


您正在使用 componentDidUpdate() 进行网络请求并更新状态,这很好,但这会重新触发 componentDidUpdate()。所以它被一遍又一遍地调用。这也在官方文档中得到解决。

所以你应该使用参数来检查你是否需要网络请求。例如:你可以这样做:

componentDidUpdate(prevProps, prevState) {

    // check if dataSource state is still empty
    if (!prevState.dataSource) {

         // Your networking code
         return fetch(...)
             .then(...)
             .catch(...)
    }
}

现在网络调用仅在需要时执行,并且不会一遍又一遍地调用 componentDidUpdate()。

注意:如果 dataSource 状态不需要为空,那么您还可以在 if(...) 语句中将当前状态/props 与之前的 state/props 进行比较。


推荐阅读