React Encountered two children with the same key

1.1k Views Asked by At

I am making a test news app with infinite scroll react but when I scroll for more news I got the same news that I have seen above and get the error in console like:

react-dom.development.js:67 Warning: Encountered two children with the same key, https://www.nytimes.com/2022/04/01/movies/oscars-will-smith-slap.html. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version. at div at div at div at div at InfiniteScroll (http://localhost:3000/static/js/bundle.js:35314:24) at New (http://localhost:3000/static/js/bundle.js:590:5) at Routes (http://localhost:3000/static/js/bundle.js:37042:5) at Router (http://localhost:3000/static/js/bundle.js:36975:15) at BrowserRouter (http://localhost:3000/static/js/bundle.js:36451:5) at div at App (http://localhost:3000/static/js/bundle.js:36:5)

The place where I am using the keys is app

import NewsIItem from './NewsIItem'
import InfiniteScroll from 'react-infinite-scroll-component';
import ScrollLoader from './ScrollLoader';
export class New extends Component {

  static defaultProps = {
    category: "general"
  }
  // static propTypes = {
  //   category : PropTypes.string
  // }
  constructor() {
    super();
    this.state = {
      articles: [],
      loading: false,
      page: 1,
      totalResults: 0

    }
  }
  async componentDidMount() {
    // console.log("Inside the cdm");
    let myUrl = `https://newsapi.org/v2/top-headlines?country=us&category=${this.props.category}&apiKey={private}&page=1&pageSize=${this.props.pageSize}`
    let data = await fetch(myUrl)
    let parsedData = await data.json()
    console.log(parsedData);
    this.setState({ articles: parsedData.articles, totalResults: parsedData.totalResults })
  }

  fetchData = async () => {
    this.setState({
      page: this.state.page + 1
    })
    let myUrl = `https://newsapi.org/v2/top-headlines?country=us&category=${this.props.category}&api= {private}&page=1&pageSize=${this.props.pageSize}`
    this.setState({ loading: true })
    let data = await fetch(myUrl)
    let parsedData = await data.json()
    console.log(parsedData);
    this.setState({ articles: this.state.articles.concat(parsedData.articles), totalResults: parsedData.totalResults, loading: false })
  }
  render() {
    return (
      <>

        <h2 className="headlines text-center">Newsers Most updated ~ Headlines</h2>
        <InfiniteScroll
          dataLength={this.state.articles.length} //This is important field to render the next data
          next={this.fetchData}
          hasMore={this.state.articles.length !== this.state.totalResults}
          loader={<ScrollLoader />}
        >
          <div className="container">

            <div className="row my-3">
              {this.state.articles.map((element) => {
                return <div className="col-md-4" key={element.url}>
                  <NewsIItem title={element.title} description={element.description} imageUrl={!element.urlToImage ? "https://i.pinimg.com/originals/d1/a6/2a/d1a62a6d8969170025f279115470e34b.jpg" : element.urlToImage} newsId={element.url} />
                </div>
              })}
            </div>
          </div>
        </InfiniteScroll>


      </>

    )
  }
}

export default New

2

There are 2 best solutions below

2
On

Yo have this line twice:

<Route exact path="/sports" element={<New key= "sports" pageSize={this.pageSize} category="sports" />} />

Remove one or change the key values.

0
On

Just update this line of code:

{this.state.articles.map((element) => return <div className="col-md-4" key= 
   {element.url}>

To this

{this.state.articles.map((element,index)=> {
  return <div className="col-md-4" key={index}>