Abaixo o ciclo que seguiremos para implementar o redux na nossa aplicação:
link da imagem.
Aqui vamos fazer uma implementação sobre como utilizar o redux no react. Basicamente teremos um input que ao digitar algo as informações serão guardadas no estado e recuperadas através de um botão que ao ser clicado mostra a informação na tela.
- 1 - Para começar vamos criar o react app
- 2 - Agora vamos instalar o redux
- 3 - Dentro da pasta src crie uma outra pasta chamada "redux" e dentro de redux crie outras três pastas, "actions", "reducers" e "store"
- 4 - O código da aplicação ficou assim
- 5 - Seguindo o ciclo
- 6 - Fazer com que tudo convese
- 7 -Agora vamos para a reta final...
- 8 - Clone do portifólio
No terminal escolha um diretório onde esse app ficará, em seguida digite o código no terminal:
npx create-react-app nome-do-app
Entre na pasta do app:
cd nome-do-app
Para iniciar o projeto no browser:
npm start
Deverá "automágicamente" abrir uma aba no navegador e aparecer algo assim:
Para instalar a biblioteca redux digite o seguinte código no terminal:
npm install --save redux react-redux
"redux" é a biblioteca que possui a implementação do Redux.
"react-redux" é a biblioteca oficial para realizar a conexão entre React e Redux.
3 - Dentro da pasta src crie uma outra pasta chamada "redux" e dentro de redux crie outras três pastas, "actions", "reducers" e "store"
src/App.js
import { Component } from 'react'
import './App.css';
class App extends Component {
render() {
return (
<section className="App-section">
<header>
<h1>React Redux</h1>
</header>
<label htmlFor="text-input">
<input name="text" id="text-input" type="text" />
</label>
<button type="button">Salvar</button>
</section>
);
}
}
export default App;
Aqui nada acontece, agora vamos partir para a implementação do redux!! 🚀
Qualquer dúvida, reveja o ciclo!
Lembra daquela pasta redux que criamos? Então, lá dentro temos uma pasta chamada actions, nesse caso vamos criar um arquivo chamado "inputActions.js", lá vamos ter o seguinte código:
src/redux/actions/inputActions.js
const INPUT_CHANGE = 'INPUT_CHANGE';
const inputAction = (text) => ({
type: INPUT_CHANGE,
text,
});
export default inputAction;
- Em uma constante declaramos a action;
- Depois criamos uma função que retorna um objeto com o tipo (type) da action e o que essa action irá receber, no caso o texto (text) do input;
- Por fim exportamos essa função;
E pronto! A nossa action está feita. 📌
Dentro da pasta redux, agora vamos utilizar a pasta reducers. Lá vamos criar um arquivo chamado inputReducer.js com o seguinte código:
src/redux/reducers/inputReducer.js
const INPUT_CHANGE = 'INPUT_CHANGE';
const INITIAL_STATE = {
text: '',
}
const inputreducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case INPUT_CHANGE:
return {
...state,
text: action.text,
};
default:
return state;
}
}
export default inputreducer;
- Novamente em uma constante declaramos a mesma action do arquivo anterior.
- Criamos um estado inicial, onde esse estado sempre é um objeto, ele pode receber string (como é o nosso caso), mas também pode recebem array, objeto, boleano.
- Depois temos uma função a qual verifica qual foi o tipo da ação efetuada, e ela atualiza o estado conforme descrevemos.
- Por fim exportamos a função.
O state é imutável. Portanto, devemos usar métodos que façam clonagem e não mutação do estado. Você pode se aprofundar um pouco mais aqui.
Depois de criar os reducers é hora de unificar todos eles através do "combineReducers". Aqui podemos criar um arquivo "index.js".
src/redux/reducers/index.js
import { combineReducers } from 'redux';
import inputreducer from './inputReducer'
const rootreducer = combineReducers({
inputreducer,
});
export default rootreducer;
- Aqui vamos importar o "combineReducers" da biblioteca "redux";
- Importamos os reducers que criamos;
- Atribuímos "combineReducers" a uma variável e ela recebe como parâmetro um objeto onde podemos colocar todos os reducers;
- Por fim, exportamos o "rootreducer";
Concluímos o reducer. 👏
OBS: se houvesse mais reducers o código ficaria assim:
import { combineReducers } from 'redux';
import inputreducer from './inputReducer'
import exempleReducer from './exempleReducer'
const rootreducer = combineReducers({
inputreducer,
exempleReducer,
});
export default rootreducer;
Agora o último mas não o menos importante, o store!
Dentro da pasta store, vamos criar um arquivo index.js com o código:
src/redux/store/index.js
import {createStore } from 'redux';
import rootreducer from '../reducers';
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;
- Primeiro importamos da biblioteca do redux a createStore;
- Depois atribuimos essa função em uma variável chamada store (pode ser outro nome, mas por boa prática usamos store),
- A função pode receber até dois parâmetros, a rootReducer onde estão concentrados todos os nossos stors e nesse caso o segundo parâmetro é para o funcionamento de uma extensão chamada Redux DevTools disponível para o chorme.
Um pouco de como ela funciona: 😊
E terminamoooos!!! 💥
ops! inda não, mas falta pouco! 👀
Agora precisamos fazer com que o react converse com o redux, e para isso vamos precisar fazer algumas alterações no nosso index.js que é responsável por renderizar toda a nossa aplicação.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './redux/store';
import App from './App';
ReactDOM.render(
<Provider store={ store }>
<App />
</Provider>,
document.getElementById('root')
);
- Precisamos importar o Provider, da biblioteca "react redux" e a nossa store do diretório onde ela se encontra;
- Basicamente o Provider que vai "prover" as informações do store;
Aqui é somente isso!:pushpin:
Agora vamos ver tudo funcionando, no App.js:
import { Component } from 'react'
import { connect } from 'react-redux';
import inputAction from './redux/actions/inputActions'
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
shouldAppear: false
}
this.handleChange = this.handleChange.bind(this);
this.clickChange = this.clickChange.bind(this);
}
handleChange({ target }) {
const { inputChange } = this.props;
const {name, value } = target;
if(name === 'text') {
inputChange(value);
this.setState({
shouldAppear: false,
});
}
}
clickChange() {
this.setState({
shouldAppear: true,
});
}
render() {
const { shouldAppear } = this.state;
const { inputState} = this.props;
return (
<section className="App-section">
<header>
<h1>React Redux</h1>
</header>
<label htmlFor="text-input">
<input onChange={this.handleChange} name="text" id="text-input" type="text" />
</label>
<button onClick={() => this.clickChange()} type="button">Salvar</button>
{shouldAppear && <p>{inputState}</p>}
</section>
);
}
}
//Pegaremos as funções das actions
const mapDispatchToProps = (dispatch) => ({
inputChange: (text) => dispatch(inputAction(text)),
});
//Pegamos o estado nos reducers
const mapStateToProps = (state) => ({
inputState: state.inputreducer.text,
})
export default connect(mapStateToProps, mapDispatchToProps)(App);
- Primeiro passo importar o connect
- Importaremos também inputAction das actions, é a função que recebe como parâmetro o texto do input, lembra? Você pode rever aqui
- Depois lá na ultima linha do código é onde "conectamos" tudo, o connect recebe dois parâmetros mapStateToProps que pega os estados no reducer. E o mapDispatchToProps que despacha o que as funções (no caso a função que importamos da action) recebem no parâmetro para a action.
- Criamos uma lógica para que a função receba o texto do input:
handleChange({ target }) {
const { inputChange } = this.props;
const {name, value } = target;
if(name === 'text') {
inputChange(value);
this.setState({
shouldAppear: false,
});
}
}
essa lógica conversa com o input:
<label htmlFor="text-input">
<input onChange={this.handleChange} name="text" id="text-input" type="text" />
</label>
- Tem outra lógica que faz com que o texto apareça ao clicarmos no botão, envolvendo apenas lógica que se aplica ao react.
E agora acabamos de verdade!!!:heart_eyes:
🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀
Caso você faça o clone do portfólio, após clonar, no terminal entre na pasta do projeto e instale as dependências necessárias digitando:
npm install
Para abrir o projeto no browser:
npm start
Sei que foi algo bem simples, mas foi mesmo para tentar passar o conceito básico do redux, espero que eu tenha conseguido ajudar de alguma forma.:smile: