React Native - componentDidUpdate导致app运行缓慢

时间:2018-04-29 18:58:51

标签: react-native

我遇到了这个问题,其他组件应该是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>
       );
     }
   }

2 个答案:

答案 0 :(得分:2)

您正在使用componentDidUpdate()来执行网络请求并更新状态,这很好,但这会重新触发componentDidUpdate()。所以它被一遍又一遍地召唤。这也在official documentation中得到解决。

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

componentDidUpdate(prevProps, prevState) {

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

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

现在,只有在需要时才会执行网络呼叫,并且不会反复调用componentDidUpdate()。

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

答案 1 :(得分:2)

你永远不应该在this.setState();内拨打componentWillUpdate, 因为一旦它更新状态,它将再次调用componentWillUpdate等等......所以这将是一个永无止境的过程,你总是可以使用if else块来检查是否更新,通过检查以前的道具因为调用componentWillUpdate而调用它(prevProps,prevState)