React Native警告:在现有状态转换(例如使用渲染)期间无法更新

堆栈溢出

我在我的本机应用程序屏幕上收到以下警告:

Warning: Cannot update during an existing state transition (such as within 'render'). Render functions should be a pure function of props and state. 

在此处输入图片说明

如您所见,它似乎与我的getVolunteerDonations方法有关。这是我的代码:

export default class ProfileScreen extends React.Component {

constructor() {
    super();
  this.state = {
    activeCard : null, 
    selectedIndex: 0,
    user: null, 
    ongoingDonations: [],
    finalizedDonations: [],
    volunteerOngoingDonations: [],
    deliveredDonations: [],
    isLoadingDonations: true,
    isLoadingDeliveries: true,
    alertStatus: "",
    alertTitle: "",
    alertMessage: ""
  };

  this.getVolunteerDonations = this.getVolunteerDonations.bind(this);
  this.getOngoingDonations = this.getOngoingDonations.bind(this);
  this.displayDropdownAlert = this.displayDropdownAlert.bind(this);

}

loadUser(){
  let userEmail = encodeURIComponent(auth().currentUser.email);
  Promise.all([
      fetch(API_URL + "/users?email=" + userEmail)
  ])
  .then(([res1]) => Promise.all([res1.json()]))
    .then(([data1]) => { 
      this.setState({
      user: data1[0]
    })})
    .catch((error) => console.log(error))
}

componentDidMount(){
  this.loadUser();
}

triggerReload (status, title, message) {
  this.setState({
    isLoadingDonations: true,
    isLoadingDeliveries: true,
    alertStatus: status,
    alertTitle: title,
    alertMessage: message
  })
}

displayDropdownAlert(status, title, message) {
  if(this.dropDownAlertRef) {
    this.dropDownAlertRef.alertWithType(status, title, message);
  }
}


getVolunteerDonations() {
  if (this.state.user != null && this.state.user.category === "Voluntario" && this.state.isLoadingDonations === false
  && this.state.isLoadingDeliveries) {
    const email = this.state.user.email.replace("+", "%2B");
    return fetch(API_URL + "/donations?volunteer=" + email)
      .then(response => response.json())
      .then(volunteerDonations => {
        let volunteerDonationsAux = [];
        let volunteeerDonationsDone = [];
        volunteerDonations.map(donation => {
          if (donation.status === 'DELIVERED' || donation.status === 'CANCELLED-BY-USER') {
            volunteeerDonationsDone.push(donation);
          } else {
            volunteerDonationsAux.push(donation);
          }
        })
        this.setState({
          volunteerOngoingDonations: volunteerDonationsAux,
          deliveredDonations: volunteeerDonationsDone,
          isLoadingDeliveries: false
        });
      });
  } else if (this.state.user != null && this.state.user.category != "Voluntario" && this.state.isLoadingDeliveries) {
    this.setState({
      isLoadingDeliveries: false
    });
  }
}

render() {


  if(this.state.alertStatus != "") {
    this.displayDropdownAlert(this.state.alertStatus, this.state.alertTitle, this.state.alertMessage);
  }

  this.getOngoingDonations();
  this.getVolunteerDonations();

  let options;
  let listData;
  let itemType;

  if (this.state.user != null) {
    if (this.state.user.category == "Donante" || this.state.user.category == "Quiero ser Voluntario") {
      options = ['Donaciones'];
      listData = this.state.ongoingDonations;
      itemType = "offer";
    } else {
      options = ['Entregas', 'Donaciones'];
      if(this.state.selectedIndex == 0) {
        listData = this.state.volunteerOngoingDonations;
        itemType = "delivery";
      } else {
        listData = this.state.ongoingDonations;
        itemType = "offer";
      }
    }
  }

  const {navigate} = this.props.navigation;
  
  if (this.state.isLoadingDonations || this.state.isLoadingDeliveries){
    return(
    <ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}>
      <Spinner isVisible={true} size={100} type={'Pulse'} color={'#013773'}/>
    </ScrollView>
    )
  } else {
  
    const getHeader = () => {
      return <View>
        <Ionicons name="ios-settings" size={40} color="#013773"
          onPress={() => navigate('Configuración', {user: this.state.user, finalizedDonations: this.state.finalizedDonations, deliveredDonations: this.state.deliveredDonations})}
          style={{position: "absolute", right: 10}}/>
         <View style={{marginTop: 45, alignItems: "center"}}>
            <View style={styles.avatarContainer}>
                <Image style={styles.avatar}
                source={require('../../../assets/logo.png')}/>
            </View>
            <Text style={styles.name}> {auth().currentUser.displayName} </Text>
         </View>
          <View style={styles.stat}>
            <Text style={styles.statTitle}> {this.state.user.category === "Voluntario" ? "Voluntario": "Donante"} - {this.state.user.phone}  </Text>
            <Text style={styles.statTitle}> {this.state.user.email} - {this.state.user.address}  </Text>
            {this.state.user.category === "Donante" ? <Button
            buttonStyle={styles.wantVolunteer}
            title='Quiero ser voluntario' onPress={() => navigate("Quiero ser voluntario", {user: this.state.user, finalizedDonations: this.state.finalizedDonations, deliveredDonations: this.state.deliveredDonations})}/>
            : null}
          </View>
         {this.renderSummary()}
         {options.length > 1 ?
         <SegmentedControlTab
         values={options}
         selectedIndex={this.state.selectedIndex}
         onTabPress={this.handleIndexChange}
         tabsContainerStyle={styles.tabsContainerStyle}
         tabStyle={styles.tabStyle}
         tabTextStyle={{fontSize: 18, color: '#013773'}}
         activeTabStyle={{ backgroundColor: '#013773' }}
         /> : 
         null}
      </View>
    }

    const getFooter = () => {
      if(listData.length <= 0){
        return <View style={{alignItems: 'center'}}>
          <Text style={styles.nostuff}> ¡Nada para mostrar! </Text>
          </View>;
      }
      return null;
    }  

    return (
      <View>
        <FlatList
          data={listData}
          renderItem={({ item }) => <ProfileItem itemType={itemType} item={item} volunteer="test" triggerAlert={this.displayDropdownAlert.bind(this)} updateParentState={this.triggerReload.bind(this)}/>}
          keyExtractor={(item, index) => index.toString()}
          ListHeaderComponent={getHeader}
          ListFooterComponent={getFooter}
          onRefresh={() => this.triggerReload("", "", "")}
          refreshing={this.state.isLoadingDonations}
        />
        <DropdownAlert ref={ref => this.dropDownAlertRef = ref} />
      </View>
    );
  }
 }
}

抱歉,代码太长,但我不确定是否相关。我试图删除一些功能使其更短一些。如您所见,我在我的render方法中调用了getVolunteerDonations。

橡木

我认为问题可能在于您正在渲染中调用getVolunteerDonations函数,但是该函数确实设置了setState。每当您使用setState时,您都会重新渲染,因此这是一个恶性循环。

您确定需要在render中调用该函数吗?

我建议您在componentDidMount中调用getVolunteerDonations函数,或者如果您首先依赖loadUser调用,则在loadUser函数的.then()中调用getVolunteerDonations。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

React Native警告:在现有状态转换期间(例如在`render`中)无法更新

添加react-native-router-flux Action()之后,“警告:setState(...):在现有状态转换期间无法更新”

React Native / Redux-setState-在现有状态转换期间无法更新

“无法在现有日期转换期间更新”在 react-native 中使用带有 redux 的 react-navigation

在React中现有的状态转换错误期间无法更新

React中的“无法在现有状态转换期间更新”错误

反应警告:在现有状态转换期间(例如在`render`中)无法更新

警告:在现有状态转换期间(例如在`render`中)无法更新。渲染方法应该是道具和状态的纯函数

收到警告:渲染内部现有状态转换期间无法更新

使用useMemo在渲染期间更新React Hooks状态

警告:setState(...):在现有状态转换期间无法更新

警告:setState(…):在现有状态转换期间无法更新

React - setState errir - 在状态转换期间无法更新

警告:无法在现有状态转换期间更新(例如在 `render` 或其他组件的构造函数中)

无法从渲染方法React更新状态

React-Native:警告:无法在已卸载的组件上执行React状态更新

ES6-警告:setState(…):在现有状态转换期间无法更新

ReactJS:警告:setState(...):在现有状态转换期间无法更新

React Native无法使用强制更新或设置状态呈现页面

反应错误:“无法在现有状态转换期间更新”

ReactJS | 在现有状态转换期间无法更新

无法在现有状态转换错误期间更新

使用 React Native 和 Hooks 时,状态不会在 Jest 测试期间更新

setState(...):无法在现有状态转换期间更新(例如在 `render` 或其他组件的构造函数中)

在react-native中更新redux状态后的渲染屏幕

ReactNative:在现有状态转换期间(例如在`render`中)不能更新。渲染方法应该是道具和状态的纯函数

由于在渲染方法中调用了 onClick 方法,因此出现“无法在现有状态转换期间更新”错误

React 无法更新状态

在现有状态转换期间无法更新-不使用任何非法的setState()