componentDidUpdate不断被调用

时间:2019-01-23 08:03:51

标签: reactjs react-native

 componentDidUpdate () {
        this.showPosts();   
  }

showPosts = async () => {

    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) => {

        let jsonObj = JSON.parse(JSON.stringify(responseJson));

        if (jsonObj.status=="true") {

            this.setState({ 
                data: responseJson.data, 
                imageSrc: responseJson.data.imgSrc,
            });    
        } 
        else {       
                this.setState({show: false});
        }  

        })      
  }

我正在从componentDidUpdate调用showPosts函数以显示更新后的Flatlist。但是componentDidUpdate不断被调用。我应该使用shouldComponentUpdate吗?

=========================更新代码================== =========

这来自主屏幕

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

componentDidUpdate () {
     this.showPosts();   
}



 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) => {

    let jsonObj = JSON.parse(JSON.stringify(responseJson));

    if (jsonObj.status=="true") {

        this.setState({ 
            data: responseJson.data, 
            imageSrc: responseJson.data.imgSrc, 
        });

    } 
    else {
        if (this._isMounted) {
            this.setState({show: false});
        }
    }  

    })
    .catch((error) => {
        console.error(error);
    });
}
catch (err) {
    console.warn(err);
  }

  }

  componentWillUnmount () {
    this._isMounted = false;
  }

这是图像描述屏幕,从这里我将导航回主屏幕

    postData = async () => {

    this.setState({loading: true});

    var location = await AsyncStorage.getItem('location');
    var path = await AsyncStorage.getItem('path');
    var post_type = await AsyncStorage.getItem('post_type');
    var userId = await AsyncStorage.getItem('userID');

    var newPath = path.split("/");
    var imageName = newPath[newPath.length-1];

    const formData = new FormData();

    var media = {
        uri: path,
        name: imageName,
        type: 'image/jpg',
    };

    formData.append('image', media);
    formData.append('user', userId);
    formData.append('description',this.state.description);
    formData.append('location',"usa");
    formData.append('post_type',post_type);
    formData.append('userprofile_picture',imageName);


    fetch(strings.baseUri+"addPosts",{
        method: 'POST',
        headers: { 'Content-Type': 'multipart/form-data' },
        body: formData,
      })
      .then((response) => response.json())
      .then((responseJson) => {

         let jsonObj = JSON.parse(JSON.stringify(responseJson));

         if (jsonObj.status=="true") {  

            this.props.navigation.popToTop() 
            && this.props.navigation.navigate('Home'); // This navigates me to the HomeScreen

         } 
         else {

         } 
      })
      .catch((error) => {
          console.error(error);
      });

  }

4 个答案:

答案 0 :(得分:3)

ComponentDidUpdate LifeCycle Hook 的更新,当组件 State Props中发生更改时,将触发此更新。

输入您的代码: 您正在调用 showPosts setState 的处理程序,这将再次触发更新生命周期。

这将导致无限循环。

  

解决方案

  1. 如果您只想在第一时间加载帖子,请移至 Creativity 生命周期挂钩( componentDidMount )。

    componentDidMount() { // This just gets called once in creational lifecycle //
        this.showPosts();  } 
    
  2. 如果要始终获取最新数据,则有两种方法

    • 更新组件位于同一组件树分支中:在这种情况下,很容易实现这一点,您可以将 state 从更新组件传递到子组件有道具,您的工作就完成了,或者如果他们是兄弟姐妹,则进行升级,您可以将状态上移一个级别,并让它进入并具有道具。
    • 更新组件位于不同的组件树分支中:我建议使用REDUX,这是redux的主要用法。

shouldComponentUpdate 是的,可以肯定的是,如果需要,您可以使用它来验证数据和负载,但是使用此组件时,请务必小心,组件更新取决于其中的代码。

请检查https://reactjs.org/docs/react-component.html#shouldcomponentupdate

答案 1 :(得分:1)

您也可以这样做

  

公共父组件

创建一个新组件,例如帖子

import React, { Component } from 'react';
import HomeScreen from '../../HomeScreen';
import ImageDescription from '../../ImageDescription';

class Posts extends Component {

    constructor(){
     super();
     this.state = {
       dataEditted: false;
     }
    }

    newDataHandler = () =>{
      this.setState({dataEditted:true}); // this is flag to identify that there is change in data //
    }

    resetnewDataHandler = () =>{
      this.setState({dataEditted:false}); // this handler is used to reset the falg back to initial //
    }

    render () {
        const homeScreen =  <HomeScreen editted={this.state.editted} resetHandler={this.resetnewDataHandler}/>;
        const imageDescription = <ImageDescription newdataHandler={this.resetnewDataHandler}/>

        return (
            <div>
            {homeScreen}
            {imageDescription}
            </div>
        )
    }
}

export default Posts;

此组件将用作在其间移动数据的桥梁。

只要 ImageDescription 组件中有新数据,就使用传递给newDataHandler的{​​{1}}来更新公共父对象,然后将 dataEditted 更新并传递给 homeScreen组件的道具,现在在 homeScreen 的此props中,检查其是否为真,然后调用componentDidUpdate并同时调用{{ 1}}。

答案 2 :(得分:0)

componentDidUpdate在状态更改时被调用(调用setState()),并且如果您在也位于componentDidUpdate内部的showPosts中执行此操作,则会创建无限状态更新。

答案 3 :(得分:0)

如果您在ComponentDidUpdate中进行操作,并通过ComponentDidUpdate来更新方法调用中的状态,则只需以这种方式进行调用即可。

componentDidMount () {
        this.showPosts();   
  }

================编辑=====================

如果您只想使用ComponentDidUpdate,则可以使用它。

componentDidUpdate(prevProps, prevState) {
// only update if not match I don't know what's your data is so add a 
// simple check like we use for strings.
  if (prevState.data !== this.state.data) {
    this.showPosts();
  }
}

只需使用prevState进行匹配。