Example output
import React, { useEffect } from 'react';
import { List } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { createSlice, configureStore, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const pokemonSlice = createSlice({
name: 'pokemon',
initialState: {
list: [],
status: null,
error: null,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchPokemon.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchPokemon.fulfilled, (state, action) => {
state.status = 'succeeded';
state.list = action.payload;
})
.addCase(fetchPokemon.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
},
});
const fetchPokemon = createAsyncThunk('pokemon/fetchPokemon', async () => {
const response = await axios.get('https://pokeapi.co/api/v2/pokemon?limit=100');
const results = response.data.results;
const pokemonList = await Promise.all(
results.map(async (result) => {
const pokemonResponse = await axios.get(result.url);
return pokemonResponse.data;
})
);
return pokemonList;
});
const store = configureStore({
reducer: {
pokemon: pokemonSlice.reducer,
},
});
function PokemonList() {
const dispatch = useDispatch();
const pokemonList = useSelector((state) => state.pokemon.list);
const pokemonStatus = useSelector((state) => state.pokemon.status);
const error = useSelector((state) => state.pokemon.error);
useEffect(() => {
dispatch(fetchPokemon());
}, [dispatch]);
if (pokemonStatus === 'loading') {
return <div>Loading...</div>;
} else if (pokemonStatus === 'failed') {
return <div>{error}</div>;
}
return (
<List
grid={{ gutter: 16, column: 4 }}
dataSource={pokemonList}
renderItem={(pokemon) => (
<List.Item>
<img src={pokemon.sprites.front_default} alt={pokemon.name} />
<p>{pokemon.name}</p>
</List.Item>
)}
/>
);
}
export default PokemonList;