2017-01-16 85 views
0

我想在我的React项目中做两个AJAX调用,并根据收到的数据让我的UI呈现。这是我的渲染方法:反应:状态不会在AJAX调用后得到更新

render() { 
    if (this.state.examsLoaded) { 
     return (
      <div> 
       <Button onClick={this.openModal}>Details</Button> 
       <Modal show={this.state.modalOpen} onHide={this.closeModal}> 
        <Modal.Header closeButton> 
         <Modal.Title>{this.props.course.name}</Modal.Title> 
        </Modal.Header> 
        <Modal.Body> 
         <DetailModalContent course={this.props.course} exams={this.exams} grades={this.grades}/> 
        </Modal.Body> 
        <Modal.Footer> 
         <Button onClick={this.closeModal}>Sluiten</Button> 
        </Modal.Footer> 
       </Modal> 
      </div> 
     ) 
    } 
    else { 
     return (
      <div>Loading...</div> 
     ) 
    } 
} 

渲染方法检查AJAX数据可用但如果没有,只是呈现一个“正在载入”消息。这是提取数据的代码:

componentDidMount() { 
    fetch('http://localhost:8080/course/' + this.props.course.id + '/exams').then((examResp) => { 
     examResp.json().then((examData) => { 
      this.exams = examData; 
      console.log('Course data fetched'); // THIS APPEARS 


      fetch('http://localhost:8080/user/1/grades').then((gradeResponse) => { // THIS DATA IS FETCHED 
       console.log('Done fetching grades'); // THIS APPEARS 
       gradeResponse.json((gradeData) => { 
        console.log('Parsed JSON'); // Here is where it goes wrong. This no longer appears. 
        this.grades = gradeData; 

        this.setState({ 
         examsLoaded: true, 
         modalOpen: false 
        }); 
       }); 
      }); 
     }); 
    }); 
}, 

奇怪的是,我以前只有1个提取方法,一切都会正常工作。只要我呼叫setState,组件会重新显示并显示数据。但是,添加第二个后,它不再工作。看我的console.log的。一切工作正常“,直到我解析JSON,之后,没有任何东西可以运行了。

我在做什么错? 谢谢!

+0

在一个侧面说明,你应该在组件的状态下保存数据,而不是直接作为道具(this.grades)。你能验证第二个Ajax调用的返回值是什么吗?也许它是畸形的? –

+0

@TMitchell是的我应该确实...我可以验证数据是完全正确的。 –

回答

1

fetch的json()方法返回一个promise。您在第一次调用中正确使用它,但第二次调用您将它视为功能而不是承诺。

尝试

gradeResponse.json().then((gradeData) => { 
    ... 
}); 
+0

啊,基本上只是一个错字!太傻了...非常感谢你:) –

+0

@RoemerBakker无后顾之忧,有时候最明显的事情是最难找到的东西 –

-1

您需要在componentDidUpdate中写入此逻辑。 componentDidMount将仅在第一次触发。

请参阅阵营documentation.

也许你会需要同时componentDidMount和componentDidUpdate。

componentDidMount() { 
fetch('http://localhost:8080/course/' + this.props.course.id + '/exams').then((examResp) => { 
    examResp.json().then((examData) => { 
     this.exams = examData; 
     console.log('Course data fetched'); // THIS APPEARS 
       this.setState({ 
        examsLoaded: true 
       }); //At this point some state is changed, so componentDidUpdate will be triggered. Then in that function below, grades will be fetched and state is changed, which should call render again. 

    }); 
    }); 
}, 

    componentDidUpdate(){ 
     fetch('http://localhost:8080/user/1/grades').then((gradeResponse) => { // THIS DATA IS FETCHED 
      console.log('Done fetching grades'); // THIS APPEARS 
      gradeResponse.json((gradeData) => { 
       console.log('Parsed JSON'); // Here is where it goes wrong. This no longer appears. 
       this.grades = gradeData; 

       this.setState({ 
        examsLoaded: true, 
        modalOpen: false 
       }); 
      }); 
     }); 

    } 

因为我现在没有反应环境。我会尽快更新。

+0

所以我应该能够保持渲染方法不变,并将'componentDidMount'重命名为'componentDidUpdate'? –

+0

@Amit Teli你说的是真的。但componentDidMount中的ajax调用是异步的,并且都是作为第一次调用的一部分解析的,所以它可以保持在它的位置。 –

+0

@TMitchell那么我该怎么做?他们现在不工作。 –