#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. нет, я говорю, что, поскольку состояние вызывается дочерним компонентом до добавления обзоров, это вызывает ошибку. знаете ли вы, как я могу сделать так, чтобы сначала вызывался вызов выборки в родительском компоненте, а затем он передавался дочернему компоненту?