Как остановить загрузку дочернего компонента React до передачи ему данных из вызова выборки в родительском

#javascript #reactjs #components #react-component

#javascript #reactjs #Компоненты #реагирующий компонент

Вопрос:

Я создаю веб-сайт, на котором отображаются приложения и их обзоры. у каждого приложения есть страница, и каждая страница содержит обзоры приложений. было бы очень просто, если бы обзоры были частью данных, возвращаемых при каждом вызове API приложений, но обзоры являются их собственным объектом с их собственным вызовом. итак, в основном я хотел бы, чтобы страница приложений загружала обзоры. проблема в том, что я продолжаю получать ошибки, потому что мой дочерний компонент по какой-то причине отображается дважды, и в первый раз он отображается без отзывов. по какой-то причине я не понимаю, что он загружается перед родительским компонентом. Я подтвердил это, распечатав реквизиты на консоли на каждом шаге. порядок отображения данных таков: реквизит печатается из дочернего компонента (не включает обзоры, поэтому я получаю неопределенную ошибку при попытке извлечь какие-либо данные), реквизит печатается из дочернего компонента (в комплекте с обзорами), а затем данные из асинхронного componentDidMount() печатаются последними. Я использую асинхронный componentDidMount(), потому что у меня создалось впечатление, что помещение await this.fetchData() внутри componentDidMount() заставит его ждать, пока данные не будут извлечены. это не так. так что да, если кто-нибудь может сказать мне, как загрузить это один раз и правильно, это было бы здорово. Я пробовал всевозможные разные вещи, поэтому, если что-то не имеет смысла или не складывается, это, вероятно, из более ранней попытки, и я уточню в редактировании.

вот код для родительского компонента

 import React from 'react';
import Header from '../universal components/Header';
import DetailsAppHeader from '../details page components/DetailsAppHeader';
import FeatsComponents from '../details page components/FeatsComponents';
import SupportComponent from '../details page components/SupportComponent';
import ReviewsComponent from '../details page components/ReviewsComponent';

export default class DetailPageComponent extends React.Component {
    constructor(props){
        super(props);
        
        this.state = {
            // a bunch of stuff relating to the apps
        }

    async componentDidMount() {
        await this.fetchData()
       // this await is basically useless but it's the last thing I tried 
    }

    fetchData(){
        fetch("http://localhost:3001/reviewsForApp/"   this.state.appId)
        .then(response => response.json())
        .then(response => {
            this.setState({reviews: response.data.list})
        })
    }

    render(){
        return(
            <div>
                <div>
                    <div class="col-10 offset-1">
                        <Header />
                        <DetailsAppHeader appDetails={this.state} />
                        <FeatsComponents appDetails={this.state} />
                        <SupportComponent appDetails={this.state} />
                        <ReviewsComponent appDetails={this.state}/>
                    </div>
                </div>
            </div>
        )
    }
}
 

и дочерний компонент

 import React from 'react';


const ReviewsComponent = (props) => (
     <div>
          {props.appDetails.reviews amp;amp; <h3>Most Recent Reviews</h3>}
          {console.log(props.appDetails.reviews)}
          // first time returns undefined the second time it returns the correct data
          <p>{props.appDetails.reviews}</p>
          // this fails because the data is not loaded yet
     </div>
   )


export default ReviewsComponent;
 

Ответ №1:

Возможно, попробуйте отображать дочерние компоненты только тогда, когда состояние заполнено, например:

 render(){ return(
<div>
  <div>
    <div class="col-10 offset-1">
      <Header /> {this.state amp;amp; (
      <DetailsAppHeader appDetails={this.state} />
      <FeatsComponents appDetails={this.state} />
      <SupportComponent appDetails={this.state} />
      <ReviewsComponent appDetails={this.state}/> ) }
    </div>
  </div>
</div>
) } 

Комментарии:

1. это делает так, что данные вызываются только один раз. к сожалению, при первой загрузке данных в ReviewsComponent.js он загружается без отзывов. знаете ли вы, как это сделать, чтобы я либо А) получал данные из второго вызова рендеринга? или Б) визуализировать обзоры за 1 попытку?

2. Я предполагаю, что вы так говорите, потому что состояние заполнено другими данными. Как насчет проверки с помощью this.state.reviews?

3. Я вижу, что вы добавили логику проверки null в дочерний компонент ReviewsComponent . Включите <p>{props.appDetails.review}</p> внутри {props.appDetails.reviews amp;amp; <h3>Самые последние обзоры</h3>} .

4. {props.appDetails.reviews ? <div> <h3>Самые последние обзоры</h3> <p>{props.appDetails.reviews}</p> </div> : null}

5. нет, я говорю, что, поскольку состояние вызывается дочерним компонентом до добавления обзоров, это вызывает ошибку. знаете ли вы, как я могу сделать так, чтобы сначала вызывался вызов выборки в родительском компоненте, а затем он передавался дочернему компоненту?