1

I am building a basic react app combined with the Pokeapi. Whenever the user types something in the input field of my pokedex, I want to update the state to then (onSubmit) find this pokemon in the Pokeapi.

Whenever I log the state (in the state update function), it logs the state -1 character as typed in the input field.

Printscreen of result

Snippet of component:

import React, { Component } from 'react';

export default class Pokedex extends Component {
    constructor(props) {
        super(props);
        this.state = {
            pokemon: "",
            result: {}
        }
    }
    setPokemon(value) {
        this.setState({
            ...this.state.pokemon,
            pokemon: value.toLowerCase()
        });
        console.log(this.state.pokemon);
    }
    render() {
        return (
            <div className="container-fluid">
                <div className="pokedex row">
                    <div className="col-half left-side">
                        <div className="screen"/>
                        <div className="blue-button"/>
                        <div className="green-button"/>
                        <div className="orange-button"/>
                    </div>
                    <div className="col-half right-side">
                        <input type="text" placeholder="Find a pokemon" onChange={(e) => this.setPokemon(e.target.value)}/>
                    </div>
                </div>
            </div>
        )
    }
}

Why does this happen?

Regentix
  • 293
  • 1
  • 4
  • 14

2 Answers2

3

setState is an async function. That means using console.log immediately after setState will print the last state value. If you want to see the latest updated value then pass a callback to setState function like this

setPokemon(value) {
    this.setState({pokemon: value.toLowerCase()},
    () => console.log(this.state.pokemon));
}
Prakash Sharma
  • 15,542
  • 6
  • 30
  • 37
1

This first way you can directly set the state of pokemon inside of the input.

<input type="text" placeholder="Find a pokemon" onChange={(e) => this.setState({ pokemon:e.target.value }) }/>

remove the function set pokemon.

 setPokemon(value) {
        this.setState({
            ...this.state.pokemon,
            pokemon: value.toLowerCase()
        });
        console.log(this.state.pokemon);
    }

theres no reason to use the spread operator, all you would simply do if you did want to use a setter is,

setPokemon = (value) => {
 this.setState({ pokemon:value })
}

but even then the first way is better.

Theres also

setPokemon = (e) => {
     this.setState({ pokemon:e.target.value })
    }

then in input <input onChange={this.setPokemon()} />

Omar
  • 3,401
  • 2
  • 23
  • 40
  • You're right. The spread operator isn't necessary here. But why does this behaviour happen? Also, isn't your way, a different way to rome? Because up on using the example you provided, i still get the same "strange behaviour" as shown above. – Regentix Mar 11 '18 at 17:10