Реагировать на сохранение состояния предыдущего компонента и визуализацию нового состояния

Я работаю над новостным приложением, в котором я вызываю API и отображаю карточки с актуальными новостями (рисунок 1).

  <div style={{display: 'flex', flexWrap: 'wrap', padding: 20, alignItems: 'center', justifyContent: 'center' }}>
      {this.state.news.map(news => (
        <NewsCard
          key={news.url}
          _id={news.url}
          description={news.description}
          image={news.urlToImage}
          source={news.source.name}
          title={news.title}
          summary={this.state.summary}
          onExpand={this.handleDetailClick.bind(this, news.url)}
          onSave={this.handleDetailClick.bind(this, news.url)}
        />
    ))}
    </div>

При раскрытии карты отображается суть статьи после вызова второго API (рис. 2).

  handleDetailClick = link => {
// console.log('hadle detail', link);
API.summarize(link)
  .then((res) => {
    // console.log(res.body);
    this.setState({
      summary: res.body
    })
    // console.log(this.state.summary);
  })

}

Однако я застрял в этой проблеме, после чего при вызове gist API на второй карте первая карта получает суть второй карты. Как этого избежать? (рисунок 3)

До сих пор я пытался использовать метод жизненного цикла componentDidUpdate для сравнения состояний и сохранения постоянного состояния для первой карты, но я не могу понять это.

Любые указатели?

b0b1b2


person Yash    schedule 04.03.2019    source источник
comment
Можете ли вы включить соответствующий код для этого?   -  person Henry Woody    schedule 04.03.2019
comment
добавил немного кода   -  person Yash    schedule 04.03.2019


Ответы (1)


Вам нужно каким-то образом связать данные summary с нужными новостями. В настоящее время ваша программа просто передает текущий summary всем NewsCard компонентам.

Самый простой способ сделать это с вашим текущим кодом - также записать URL-адрес, из которого получена сводка, в состоянии вашего основного компонента (родителя компонентов NewsCard). Затем только передайте сводку нужной новости.

Например (добавляя summaryUrl к state) (обратите внимание на строку summary=):

<div style={{display: 'flex', flexWrap: 'wrap', padding: 20, alignItems: 'center', justifyContent: 'center' }}>
  {this.state.news.map(news => (
    <NewsCard
      key={news.url}
      _id={news.url}
      description={news.description}
      image={news.urlToImage}
      source={news.source.name}
      title={news.title}
      summary={news.url === this.state.summaryUrl ? this.state.summary : ""}
      onExpand={this.handleDetailClick.bind(this, news.url)}
      onSave={this.handleDetailClick.bind(this, news.url)}
    />
))}
</div>

Таким образом, мы передаем this.state.summary в NewsCard только в том случае, если URL-адрес текущей новости совпадает с URL-адресом сводки.

Затем метод handleDetailClick следует обновить до:

handleDetailClick = link => {
  // console.log('hadle detail', link);
  API.summarize(link)
  .then((res) => {
      // console.log(res.body);
    this.setState({
     summary: res.body,
     summaryUrl: link,
    })
    // console.log(this.state.summary);
  })

}

Другой способ, который вы можете сделать, — передать второй вызов API компоненту NewsCard. Таким образом, каждый NewsCard будет иметь свою сводку как часть своего собственного состояния и будет извлекать сводку при нажатии. Таким образом, не возникнет путаницы в том, к какой новости относится сводка. Это также может помочь очистить ваш родительский компонент, делегируя задачи/данные дочерним элементам по мере роста компонента.

person Henry Woody    schedule 04.03.2019
comment
@Yash это помогло? Чего-то не хватает? - person Henry Woody; 08.03.2019