React сохраняет состояние предыдущего компонента и отображает новое состояние

#reactjs #react-hooks

#reactjs #реагирующие хуки

Вопрос:

Я работаю над новостным приложением, в котором я вызываю 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

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

1. можете ли вы включить соответствующий код для этого?

2. добавлен некоторый код

Ответ №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);
  })

}
  

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

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

1. @Yash помогло ли это? Чего-нибудь не хватает?