0

Details of what I am trying to achieve:

  1. Fetch data from Pokemon API and render a few pokemons (response from API is NAME & URL of the Pokemon which leads to an end point with details about that Pokemon. I was able to fetch and receive a response which is currently being rendered on the page using the array.map() method in the form of <li> components.

  2. Created a click event on each <li> to return the index of that element. The goal is to pass this index to another component where another fetch request is being made based on the index of this element. E.g. if user clicks Pokemon "A" then I am hitting the API with "A" to retrieve Pokemon "A" details back and render the on to the page.

My issue is that the onClick function isn't performing correctly. I have to hit the <li> Pokemon </li> twice to get the index of that element.

class PokemonList extends Component {
    constructor () {
        super();
        this.state = {
            currPoke: null,
        }
    }    

    pokeClicked(index){
        console.log('poke got clicked-->', this.state.currPoke);
        this.setState({
            currPoke: index+1,
        }) 

         console.log('after set state', this.state.currPoke);
    }    
    render () {
        return(
               <div className="list">     
                    <ul>
                        {this.props.apiData.map((p, index) => {
                            return <li onClick={()=>{this.pokeClicked(index)}} key={index}>{p.name.charAt(0).toUpperCase() + p.name.slice(1)}</li>
                        })}
                    </ul>
                    <div className="lis">
                        {this.renderClickedPoke()}
                    </div>
                </div>
            )
        } 
BSMP
  • 4,596
  • 8
  • 33
  • 44
Ash
  • 585
  • 7
  • 15
  • 1
    Have you tried `console.log(this.state)` between render and return? :) – Andrii Starusiev Aug 13 '17 at 00:08
  • so it does long the reflected click which leads to the correct index. I am trying to figure out how to pass this correct index and state as props to a different element. – Ash Aug 13 '17 at 00:21
  • Possible duplicate of [Why calling setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately) – Mayank Shukla Aug 13 '17 at 03:59

1 Answers1

1

setState is an asynchronous method (check the documentation). That's why logging your state just after setting it is not yet reflecting the change you've made to it. To see your change when it actually happens you can provide a callback as a second parameter to the setState

this.setState({
  currPoke: index+1,
}, () => { console.log(this.state.currPoke) })

Your code works as expected :)

lukaleli
  • 3,427
  • 3
  • 22
  • 32
  • Wow!! it does work. I am trying to pass the updated state to another component which is rendering the details of this poke. That component depends on this state change. Problem is that i have to hit the click twice to reflect the change. Any suggestions? – Ash Aug 13 '17 at 00:05
  • You don't have to click it twice. If you do then you have a problem in your code. But anyway I answered your question. Please mark it as a correct answer :) – lukaleli Aug 13 '17 at 00:16
  • Thanks for your help :) – Ash Aug 13 '17 at 00:20