React TypeScript right way to set select value and state

Viewed 587

I am trying to learn using TypeScript in my React projects.

I made a type for the incoming data format (name and url).

type PokedexType = {
    name: string;
    url: string;
}

The data returned from the API is an array of objects (with name and url).

{
"results": [
        {
            "name": "national",
            "url": "https://pokeapi.co/api/v2/pokedex/1/"
        },
        {
            "name": "kanto",
            "url": "https://pokeapi.co/api/v2/pokedex/2/"
        },
        // ...
    ];
}

In my useEffect(), I am storing these objects in a state with setState().

useEffect(() => {
  api.get('/pokedex')
    .then((response) => {
      setPokedex(response.data.results);
    })
    .catch((error) => {
      console.log(error);
    });
});

Because the API returns an array, I am confused about the correct way to setup useState().

// this works
const [pokedex, setPokedex] = useState<Array<PokedexType>>([{ name: "", url: "" }]);
// these also work
const [pokedex, setPokedex] = useState<PokedexType>({ name: "", url: "" });
const [pokedex, setPokedex] = useState<Array<PokedexType>>();
const [pokedex, setPokedex] = useState(); // (with checking)

I understand that specifying type is for type checking, but if the state is overwritten immediately, does this matter?

I am trying to set the states name (i.name) as value for my select, what would be the correct way to do this? Since the state is now an array, how can I set the value to the corresponding property (like this)?

<select value={pokedex.name}>
1 Answers

You can't just say pokedex.name. pokedex is an array, so you have to loop through that array. e.g.

//just a mock, will come from your ajax request
const pokedex = [
    {
        "name": "national",
        "url": "https://pokeapi.co/api/v2/pokedex/1/"
    },
    {
        "name": "kanto",
        "url": "https://pokeapi.co/api/v2/pokedex/2/"
    }
]

const Select = () => ( <select > 
      {pokedex.map(el => < option value = {el.name} >{el.name}</option>)}
</select>)


        // Render it
        ReactDOM.render( <
          Select / > ,
          document.getElementById("react")
        );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Take also a look at interfaces:

interface IPokedex {
    name: string;
    url: string;
}

const [pokedex, setPokedex] = useState<IPokedex[]>([{ name: "", url: "" }]);
Related