Nesta atividade estaremos utilizando a API Digimon para desenvolver uma aplicação onde vamos utilizar conceitos de integração com API + Redux Thunks
Antes de qualquer coisa, lembre-se te instalar as dependências:
❯ yarn add react-redux redux redux-thunk axios
É importante que não copiem o código e digitem cada linha, o fluxo do redux é complexo, e é necessária muita prática para entender o seu funcionamento.
Após gerar o projeto com nosso CRA, vamos estruturar nossa store para o projeto:
- Crie uma pasta dentro de
src
, chamadastore
. - Dentro da
store
, teremos umindex.js
, e outra pasta chamadamodules
. - Na pasta
modules
, criaremos a pastadigimons
, e dentro dela teremos o nossoreducers.js
,thunks.js
,actions.js
eactionsTypes.js
- Agora crie a pasta components, e dentro dela os seguintes componentes:
Digimons
eSearch
Neste ponto, temos a seguinte estrutura de arquivos:
É hora de configurarmos o digimon/reducers.js
, aqui você pode lembrar a configuração de reducers.js
Por conveniência, vamos utilizar o actionTypes.js
para podermos centralizar nossas actions types em um lugar só. Portanto:
-
Nossa actionTypes.js fica assim:
export const ADD_DIGIMONS = "@digimons/ADD";
-
Nosso reducer.js:
import { ADD_DIGIMONS } from "./actionsTypes"; const digimonsReducer = (state = [], action) => { switch (action.type) { case ADD_DIGIMONS: // Escreva seu case para adicionar um novo digimon. default: return state; } }; export default digimonsReducer;
-
Nosso action.js:
import { ADD_DIGIMONS } from "./actionsTypes"; export const addDigimon = (digimon) => ({ type: ADD_DIGIMON, digimon, });
-
Adicionando nosso provider ao
index.js
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { Provider } from "react-redux"; import store from "./store"; ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById("root") ); reportWebVitals();
-
Agora vamos configurar nosso
index.js
da store.import { createStore, combineReducers, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import digimonsReducer from "./modules/digimons/reducer"; const reducers = combineReducers({ digimons: digimonsReducer }); const store = createStore(reducers, applyMiddleware(thunk)); export default store;
Agora podemos começar a estruturar nossos componentes para a requisição com a API e assim renderizar nosso card.
-
Vamos importar nossos componentes
Search
eDigimons
em nossoApp.js
import logo from "./logo.svg"; import "./App.css"; import Search from "./components/Search"; import Digimons from "./components/Digimons"; function App() { return ( <div className="App"> <header className="App-header"> <Search /> <Digimons /> </header> </div> ); } export default App;
-
Agora, vamos escrever nosso componente
Search
import { useState } from "react"; const Search = () => { const [input, setInput] = useState(""); const [error, setError] = useState(false); return ( <div> <h2>Procure pelo seu Digimon!</h2> <div> <input value={input} onChange={(event) => setInput(event.target.value)} placeholder="Procure seu Digimon" ></input> <button>Pesquisar</button> </div> </div> ); }; export default Search
-
É a vez do componente
Digimons
const Digimons = () => { return ( <div> <ul> <li></li> </ul> </div> ) } export default Digimons
-
Vamos configurar nosso
thunk.js
!import axios from "axios"; import { addDigimon } from "./actions"; const addDigimonsThunk = (digimon, setError) => (dispatch) => { //Aqui faça uma requisição com o axios e em seguida, no .then() //utilize a função dispatch() passando addDigimon(response.data[0].name) } export default addDigimonsThunk
-
Agora, vamos voltar ao nosso componente
Search
, importe ouseDispatch
e oaddDigimonsThunk
. -
Crie a
**função handleSearch
,** que é responsável por chamar odispatch
passando oinput
do usuário como parâmetro. -
Faça com que o input do usuário seja passado ao state de acordo com o que ele digita. Em seguida, também configure seu button para que o onClick() chame a função handleSearch
No fim, seu componente estará parecido com isso:
import { useState } from "react";
import { useDispatch } from "react-redux";
import { addDigimonsThunk } from "../../store/modules/digimons/thunks";
const Search = () => {
const [input, setInput] = useState("");
const [error, setError] = useState(false);
const dispatch = useDispatch();
const handleSearch = () => {
setError(false);
//chame o dispatch() passando o state input
setInput("");
};
return (
<div>
<div>
<input
value={input}
onChange={} // faça com que o onChange troque o setInput
placeholder="Procure seu Digimon"
></input>
</div>
<div>
<button onClick={}>Pesquisar</button> //chamar a handleSearch
</div>
</div>
);
};
export default Search;
Voltando ao nosso componente Digimon
-
Importe o
useSelector
de react-redux.import { useSelector } from "react-redux";
-
Acesse seus digimons do state instanciado pelo useSelector.
const { digimons } = useSelector((state) => state);
-
Faça um map() para renderizar seu digimon vindo do seu estado.
const Digimons = () => { const { digimons } = useSelector((state) => state); return ( <div> <ul> {digimons.map((digimon, index) => { return //retorne o digimon; })} <li></li> </ul> </div> ); };
Se você seguiu corretamente os passos até aqui, sua aplicação deve renderizar o nome do Digimon toda vez que você procura por um nome existente e clica em pesquisar.
- Crie um componente,
DigimonList
que renderiza a lista dos digimons, e faça com que o componenteDigimon
renderize apenas um card com o respectivo Digimon. - No seu componente
Search
crie uma solução para tratar os erros caso o usuário tente procurar um digimon que não existe! - Estilize sua aplicação, retorne a imagem do digimon. Dê seu toque especial.
- Redux
- Redux-Thunk
- Request com API utilizando Redux para compartilhamento de estado