Continuamos con la serie de publicaciones donde lo dejamos: http://developinginspanish.com/2020/09/16/react-redux-tutorial-para-principiantes-ii/
Tutorial de React Redux: conectando React con Redux
Después de aprender Redux, me di cuenta de que no era tan complejo. Sabía cómo acceder al estado actual con getState. Sabía cómo enviar una acción con dispatch y cómo escuchar los cambios de estado con subscribe.
Sin embargo, no sabía cómo acoplar React y Redux. Me preguntaba: ¿debería llamar a getState desde React? ¿Cómo envío una acción desde un componente de React? Y así.
Redux es independiente del framework. Puede usarlo con Javascript vainilla. O con Angular. O con React. Hay enlaces para unir Redux con su framework/biblioteca favorita.
Para React existe react-redux, una biblioteca para la que necesita aprender solo un método por ahora:connect . ¿Qué hace? Como era de esperar, conecta un componente de React con la tienda Redux.
Utiliza connect con dos o tres argumentos según el caso de uso:
- una función mapStateToProps (también puede nombrarla «seleccionar»)
- una función mapDispatchToProps
mapStateToProps hace exactamente lo que sugiere su nombre: conecta una parte del estado de Redux a los accesorios de un componente de React. Al hacerlo, un componente React conectado tendrá acceso a la parte exacta de la tienda que necesita.
mapDispatchToProps hace algo similar, pero para acciones. mapDispatchToProps conecta las acciones de Redux con los accesorios de React. De esta manera, un componente React conectado podrá enviar mensajes a la tienda.
En la siguiente sección finalmente nos ensuciaremos las manos. Construiremos una aplicación súper simple compuesta por tres componentes:
- Un componente de la aplicación
- Un componente de lista para mostrar artículos
- Un componente de formulario para agregar nuevos artículos
Tutorial de React Redux: componente de la aplicación y tienda Redux
Antes de comenzar, instala react-redux con:
npm i react-redux --save-dev
Dije que mapStateToProps conecta una parte del estado de Redux a los accesorios de un componente de React. Quizás te preguntes: ¿es esto suficiente para conectar Redux con React? No, no lo es. También necesitamos Provider, un componente de alto nivel de react-redux.
Abre src/index.js, borra todo y actualiza el archivo con el siguiente código:
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import store from "./js/store/index";
import App from "./js/components/App";
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
Como puede ver, Provider concluye su aplicación React y la informa de toda la tienda de Redux.
Ahora creemos el componente Aplicación. No es nada especial: la aplicación debería importar un componente List y renderizarse a sí misma. Crea un directorio para contener componentes:
mkdir -p src/js/components
y un nuevo archivo llamado src/js/components/App.js:
// src/js/components/App.js
import React from "react";
import List from "./List";
const App = () => (
<div>
<h2>Articles</h2>
<List />
</div>
);
export default App;
Guarda y cierra el archivo, luego continúa con la creación de la Lista.
Tutorial de React Redux: componente de lista y estado de Redux
Hasta ahora no hemos hecho nada especial. Pero nuestro nuevo componente, List, interactuará con la tienda Redux.
Un breve resumen: la clave para conectar un componente React con Redux es connect. connect toma al menos un argumento.
Como queremos que List obtenga una lista de artículos, es cuestión de conectar state.articles con el componente. ¿Cómo? Con mapStateToProps. Tenga en cuenta que «mapStateToProps» es solo una convención, la mayoría de los desarrolladores, por ejemplo, usan «select«.
Cree un nuevo archivo llamado src/js/components/List.js. Debería verse así:
// src/js/components/List.js
import React from "react";
import { connect } from "react-redux";
const mapStateToProps = state => {
return { articles: state.articles };
};
const ConnectedList = ({ articles }) => (
<ul>
{articles.map(el => (
<li key={el.id}>{el.title}</li>
))}
</ul>
);
const List = connect(mapStateToProps)(ConnectedList);
export default List;
El componente List recibe los artículos prop, que es una copia de la matriz de artículos que vimos en el estado Redux. Viene del reductor:
const initialState = {
articles: []
};
function rootReducer(state = initialState, action) {
if (action.type === ADD_ARTICLE) {
return Object.assign({}, state, {
articles: state.articles.concat(action.payload)
});
}
return state;
}
Recuerda siempre: el estado en Redux proviene de reductores.
Finalmente, el componente se exporta como List. List es el resultado de conectar el componente sin estado ConnectedList con la tienda Redux.
¿Sigo confundido? Comprender cómo funciona Connect llevará algún tiempo. Pero no temas, el camino para aprender Redux está pavimentado con momentos de «ah-ha».
Sugiero tomar un descanso para explorar connect y mapStateToProps.
¡Dirígete a la siguiente sección cuando estés listo!
Tutorial de React Redux: componente de formulario y acciones de Redux
El componente Form que vamos a crear es un poco más complejo que List. Es un formulario para agregar nuevos elementos a nuestra aplicación y para eso usaremos una clase de JavaScript.
Descargo de responsabilidad: escribí este tutorial cuando React aún no tenía hooks. Podría usar un componente funcional aquí, pero para evitar modificar el tutorial me quedaré con las clases.
El componente de clase ayudará a mantener algunos estados locales, como entradas de formulario. También recibe una acción Redux. De esta forma, puede actualizar el estado global enviando la acción addArticle.
Crea un nuevo archivo en src/js/components/Form.js con el siguiente código:
// src/js/components/Form.jsx
import React, { Component } from "react";
import { connect } from "react-redux";
import { addArticle } from "../actions/index";
function mapDispatchToProps(dispatch) {
return {
addArticle: article => dispatch(addArticle(article))
};
}
class ConnectedForm extends Component {
constructor(props) {
super(props);
this.state = {
title: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.id]: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
const { title } = this.state;
this.props.addArticle({ title });
this.setState({ title: "" });
}
render() {
const { title } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<div>
<label htmlFor="title">Title</label>
<input
type="text"
id="title"
value={title}
onChange={this.handleChange}
/>
</div>
<button type="submit">SAVE</button>
</form>
);
}
}
const Form = connect(
null,
mapDispatchToProps
)(ConnectedForm);
export default Form;
Una breve explicación del componente:
- React estándar junto con connect y mapDispatchToProps
- mapDispatchToProps conecta las acciones de Redux con los props de React
- El método handleSubmit envía una acción
Para conectar creadores de acciones a un componente, puede utilizar el formulario de función:
function mapDispatchToProps(dispatch) {
return {
addArticle: article => dispatch(addArticle(article))
};
}
Como alternativa, también puede pasar mapDispatchToProps como un objeto. Echa un vistazo aquí.
Finalmente, el componente se exporta como Form. Form es el resultado de conectar ConnectedForm con la tienda Redux.
Nota: el primer argumento para conectar debe ser nulo cuando mapStateToProps está ausente como en nuestro ejemplo. U obtendrá el mensaje TypeError: el envío no es una función.
¡Nuestros componentes están listos! Ahora actualice la aplicación para incluir el componente Formulario:
import React from "react";
import List from "./List";
import Form from "./Form";
const App = () => (
<>
<div>
<h2>Articles</h2>
<List />
</div>
<div>
<h2>Add a new article</h2>
<Form />
</div>
</>
);
export default App;
Ejecute el servidor de desarrollo con:
npm start
Debería ver nuestra prueba de concepto funcional (en la primera versión de este tutorial usé Bootstrap y luego lo eliminé).
¡Nada sofisticado pero útil para mostrar React y Redux en funcionamiento!
El componente List de la izquierda habla con la tienda Redux. Se volverá a renderizar cada vez que agregue un nuevo elemento.
¡Lo hiciste! ¡Pero aún no hemos terminado! En la siguiente sección veremos el middleware de Redux. ¡Agárrate fuerte!
Ver la rama en Github
Hasta aquí la tercera parte de este tutorial de React Redux. Permanece atento, pronto publicaremos la cuarta parte.
Puedes leer el artículo original en inglés en: https://www.valentinog.com/blog/redux/#react-redux-tutorial-who-this-guide-is-for