Exemplo de como usar o Redux no React JS

Aprenda através um exemplo simples como usar o Redux no React JS e deixar sua aplicação mais flexível e adaptada para evoluções futuras e mais complexas

Para exemplificar o uso do REDUX em uma aplicação REACT JS, faremos uso de um cadastro simples de nomes de tarefas, onde o usuário irá incluir o nome de uma tarefa em uma lista.

Na aplicação, teremos um formulário que receberá um nome de uma tarefa e acionará uma ACTION para adicionar o nome e ativar o REDUCER para alterar, a partir do STORE, o estado da lista de nomes já incluídos. Com o estado evoluído, o componente irá renderizar na VIEW a lista de nomes.

Partimos do pressuposto que já se tenha o ambiente de desenvolvimento em React configurado, inclusive com a ferramenta create-react-app.

O código fonte da aplicação está no github.

Torne-se um programador Full Stack Javascript Profissional

Programador Full Stack JavaScript Profissional

RELACIONADO – Como entender React e como funciona o React JS?

Criar a aplicação

create-react-app react-cadastro-tarefas-redux

Remover arquivos

Depois de criada a aplicação, excluir os seguintes arquivos:

– App.css

– App.js

– App.test.js

– index.css

– logo.svg

Criar a estrutura de pastas da aplicação

Dentro da pasta src criar as seguintes pastas:

– src/components/

– src/components/todo/

– src/components/main/

– src/actions/

– src/reducers/

– src/store/

Ajustar estrutura inicial do projeto

Como realizamos diversas exclusões, vamos ajustá-la para poder compilar normalmente.

Vamos criar o componente App.jsx dentro da pasta src/components/main/ com o seguinte conteúdo:

import React from 'react';

function App() {
    return (
        <div>
            <h1>Cadastro de tarefas</h1>
        </div>
    );
}
export default App;


Em seguida ajustar o arquivo index.js com o seguinte conteúdo:

import React from 'react';
import ReactDOM from 'react-dom';

import * as serviceWorker from './serviceWorker';

import App from './components/main/App';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

Depois disso, executar dentro da pasta raiz do projeto, o comando npm start e verificar se compilou e exibiu o nome Cadastro de tarefas no browser.

Adicionar as bibliotecas do redux e do react-redux

npm install redux react-redux

Criar um arquivo de constantes de Actions

Criar um arquivo de contantes relativo às ações que poderão ser realizadas no componente de tarefas, o actionTypes.js dentro de src/actions/ com o seguinte conteúdo:

export const ADD_TODO = ‘ADD_TODO’;

Criar o Reducer relativo ao estado do componente de tarefas.

Dentro da pasta reducers, criar um arquivo todoReducer.js (src/reducers/todoReducer.js) com o seguinte conteúdo:

import {ADD_TODO} from ‘../actions/actionTypes’;

const initialState ={

todos :[],

showTodos: false

}

export const TodoReducer = (state= initialState, action) =>{

switch (action.type){

case ADD_TODO:

return {

…state,

todos: state.todos.concat(action.payload),

showTodos: true

}

default:

return state;

}

}

Criar o reducer raiz

Embora nossa aplicação seja pequena, é uma boa prática criar um reducer que junte todos os outros que existirem na aplicação.

Dentro da pasta reducers, criar um arquivo rootReducer.js (src/reducers/rootReducer.js) com o seguinte conteúdo:

import {combineReducers} from ‘redux’;

import {TodoReducer} from ‘./todoReducer’

export const RootReducer = combineReducers({todoAction: TodoReducer});

Criar a action para inclusão de uma nova tarefa

Dentro da pasta actions criar o arquivo todoAction.js (src/actions/todoAction.js) com o seguinte conteúdo:

import {ADD_TODO} from ‘./actionTypes’;

export const addTodo = todoName => ({

type: ADD_TODO,

payload: todoName

})

Criar o store

Dentro da pasta store, criar o arquivo store.js (src/store/store.js) com o seguinte conteúdo:

import {createStore} from ‘redux’;

import {RootReducer} from ‘../reducers/rootReducer’;

export const Store = createStore(RootReducer);

Incluir o provider do store

No arquivo index.js, deveremos incluir o provider com o store da aplicação. O arquivo index.js ficará com o seguinte conteúdo:

import React from ‘react’;

import ReactDOM from ‘react-dom’;

import {Provider} from ‘react-redux’;

import * as serviceWorker from ‘./serviceWorker’;

import App from ‘./components/main/App’;

import {Store} from ‘./store/store’;

ReactDOM.render(

<Provider store={Store}>

<App />

</Provider>

, document.getElementById(‘root’));

serviceWorker.unregister();

Criar componentes Todo

O cadastro de tarefas serão representados por 4 componentes:

1 Componente de c lasse

todo.jsx

3 Componentes funcionais

todoForm.jsx

todoItem.jsx

todoList.jsx

Todos eles ficarão na pasta src/components/todo

1. Arquivo todoItem.jsx

import React from ‘react’;

const TodoItem = (props) =>{

return (

<div>

{props.todoName}

<br/>

<br/>

</div>

);

}

export default TodoItem;

2. Arquivo todoList.jsx

import React from ‘react’;

import {connect} from ‘react-redux’;

import TodoItem from ‘./todoItem’;

const TodoList = (props) =>{

return (

<div>

{ props.todos.map(todo =>

<TodoItem key={todo} todoName ={todo}/>

)

}

</div>

);

}

const mapsStateToProps = state => ({

todos: state.todoAction.todos,

showTodos:state.todoAction.showTodos

})

export default connect(mapsStateToProps)(TodoList);

3. Arquivo todoForm.jsx

import React from ‘react’;

const TodoForm = (props) => {

return (

<div>

<form onSubmit={props.submitHandler}>

<input type=”text” name=”valueName” onChange={props.changeHandler} value={props.valueName}/>

<br/>

<br/>

<input type=”submit” value=”Add”/>

</form>

</div>

)

}

export default TodoForm;

4. Arquivo todo.jsx

import React, { Component } from ‘react’;

import {connect} from ‘react-redux’;

import {bindActionCreators} from ‘redux’;

import TodoForm from ‘./todoForm’;

import TodoList from ‘./todoList’;

import {addTodo} from ‘../../actions/todoAction’;

class Todo extends Component {

state = {

valueName: ”

}

constructor(props) {

super(props);

this.changeHandler = this.changeHandler.bind(this);

this.submitHandler = this.submitHandler.bind(this);

}

submitHandler = event => {

if(this.state.valueName !== ”){

this.props.addTodo(this.state.valueName);

this.setState({

valueName:”

})

event.preventDefault();

}

}

changeHandler = event => {

this.setState({

valueName:event.target.value

})

}

render() {

return (

<div>

<TodoForm valueName={this.state.valueName} submitHandler={this.submitHandler} changeHandler={this.changeHandler} />

<br />

<TodoList />

</div>

)

}

}

const mapDispatchToProps = dispatch => bindActionCreators({addTodo},dispatch);

export default connect(null,mapDispatchToProps)(Todo);

Ajuste no arquivo App.jsx

import React from ‘react’;

import Todo from ‘../todo/todo’

function App() {

return (

<div>

<h1>Cadastro de tarefas</h1>

<Todo/>

</div>

);

}

export default App;

Explicando a aplicação

A aplicação é um cadastro simples de nomes de tarefas feito em react utilizando o redux como gerenciador de estados.

No reducer temos o estado inicial das tarefas. Temos assim dois atributos :

1. A lista de tarefas, representada pelo array todos: []

2. Um atributo booleano para informar se a lista deverá ser exibida ou não, representado por showTodos: true. Ele poderá ser usado em evoluções futuras do projeto.

O componente de classe todo.jsx tem dois componentes funcionais:

1. todoForm.jsx: tem o objetivo de capturar o nome da tarefa e repassar ao componente Todo

2. todoList.jsx: tem o objetivo de renderizar a lista de tarefas. Dentro desse arquivo, tem um componente todoItem, que exibirá o conteúdo de cada linha da lista.

No componente Todo, temos que disparar o evento que irá acionar o reducer para evoluir o estado e adicionar a tarefa à lista.

Isso é feito a partir da conexão do mapDispatchToProps:

const mapDispatchToProps = dispatch => bindActionCreators({addTodo},dispatch);

export default connect(null,mapDispatchToProps)(Todo);

Já no componente TodoList, temos que associar a lista do reducer para exibição em tela. Isso é feito a partir do mapStateToProps:

const mapsStateToProps = state => ({

todos: state.todoAction.todos,

showTodos:state.todoAction.showTodos

})

export default connect(mapsStateToProps)(TodoList);

Para testar a aplicação, basta executar o comando npm start ou yarn start.

Facebooktwitterredditpinterestlinkedinmail , ,