How to avoid ‘children with same key’ when replacing state in ReactJs component

I figured out my mistake, and it had nothing to do with React per se. It was a classic case of missing javascript closure inside a loop.

Because of the possibility of duplicates I stored each ajax response in window.localStorage, on the movieId. Or so I thought.

In React Inifinite Scroll each item in your list is drawn sequentially with a call to the loadMore-function. Inside this function I did my ajax call, and stored the result in the browser cache. The code looked something like this:

  var cachedValue = window.localStorage.getItem(String(movieId));
  var cachedData = cachedValue ? JSON.parse(cachedValue) : cachedValue;

  if (cachedData != null) {
    comp.drawNextMovie(cachedData);
  } else { 
    $.ajax( {
      type: "GET",
      url: this.state.movieUrl + movieId,
      contentType: "json",
      success: function (movieData) {
        window.localStorage.setItem(String(movieId), JSON.stringify(movieData));
        comp.drawNextMovie(movieData);
      }
    });  
  }    

Can you spot the mistake? When the ajax-call returns, movieId is no longer what is was. So I end up storing the data by the wrong id, and get some strange React warnings in return. Because this was done inside the loadMore function called by the InfiniteScroll-module, I was not aware that this function was not properly scoped.

I fixed it by adding a Immediately-invoked function expression.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)