sinthetix / gw2-showcase

A React app for displaying your characters!
http://gw2-showcase.surge.sh
0 stars 0 forks source link

Icon Occasionally Shows Item Icon Even If Skin #6

Closed sinthetix closed 7 years ago

sinthetix commented 7 years ago

Not sure what is going on exactly but it looks like the state delay of set state might be coming into play again. Occasionally characters load with their skin icons but then I see it quickly overwritten to the item icon.

The code leads me to think that skin should be the final state set but perhaps I'm misunderstanding the way React (or even JS) works:

componentDidMount() {
    getItemInfo(this.props.item.id)
    .then((response) => {
      this.setState({
        name: response.data.name,
        rarity: response.data.rarity,
        icon: response.data.icon,
      })
    })
    .catch((error) => { console.log('Error getting item: ', error) });
    this.checkSkin(this.props.item.skin);
  }
  checkSkin(skin) {
    if (skin !== undefined) {
      getSkinInfo(skin)
      .then((response) => {
        this.setState({
          icon: response.data.icon,
          skinName: response.data.name,
          isLoadingItem: false,
        })
      })
      .catch((error) => { console.log('Error getting item: ', error); });
    } else {
      this.setState({ isLoadingItem: false });
    }
  }

Since I'm kind of clueless as to the best way to resolve it (wait until all promises are resolved? Handle state some other way? Does the app have 'enough' state to make Redux worthwhile? Is it something else entirely?)

stevestreza commented 7 years ago

Both promise responses are updating the icon state field. So, the last promise to resolve will be the one that ultimately shows up. Since these look like API requests, they can finish in either order, however the network works out. That's what's causing the "occasional" part of the problem.

To fix this, what I'd do is have separate fields for each type of icon, the itemIcon and skinIcon. Then, in your render method, do something like this:

const icon = this.state.skinIcon || this.state.itemIcon
return (
    ...
    <img src={icon} />
    ...
)

You could also wait for both promises to complete, merge the results there, and then call setState with them, but that's not strictly necessary unless you want to only re-render once.

sinthetix commented 7 years ago

thanks! I'll try your solution first. really appreciate you helpin a react newbie out ❤️ ❤️ ❤️

sinthetix commented 7 years ago

Seems to have worked! <3 <3 Thanks again @stevestreza :D