Usar Redux en una aplicación de React Native
() translation by (you can also view the original English article)
Redux es una biblioteca para la gestión del estado que asegura que la lógica de la aplicación está bien organizada y que las aplicaciones funcionan como se espera. Redux facilita la comprensión del código de la aplicación en cuanto a cuándo, dónde, por qué y cómo se actualiza el estado de la aplicación.
Redux está compuesto por las siguientes partes clave:
- acciones
- reductores
- tienda
- despacho
- selector
En este post, miraremos cada parte de la arquitectura del Redux por turnos.
Acciones y creadores de acción
Una acción es un objeto JavaScript plano que tiene un campo de tipo y una carga útil opcional. También se puede considerar como un evento que describe algo que ha sucedido.
1 |
const addTaskAction = { |
2 |
type: 'task/taskAdded' |
3 |
,payload: 'Laundry' |
4 |
}
|
Los creadores de acción son solo funciones que crean y devuelven objetos de acción.
1 |
const addTask = text => { |
2 |
return { |
3 |
type: 'task/taskAdded'', |
4 |
payload: text
|
5 |
}
|
6 |
}
|
Reductores
Un reductor es también una función que recibe el estado actual y un objeto de acción, actualiza el estado si es necesario y devuelve el nuevo estado. Un reductor no puede modificar el estado existente, sino que copia el estado existente y cambia los valores copiados. En otras palabras, el reductor debe ser una función pura.
Aquí hay un ejemplo.
1 |
const initialState = { value: 0 } |
2 |
|
3 |
function counterReducer(state = initialState, action) { |
4 |
// Check to see if the reducer cares about this action
|
5 |
if (action.type === 'counter/increment') { |
6 |
// If so, make a copy of `state`
|
7 |
return { |
8 |
...state, |
9 |
// and update the copy with the new value
|
10 |
value: state.value + 1 |
11 |
}
|
12 |
}
|
13 |
// otherwise return the existing state unchanged
|
14 |
return state |
15 |
}
|
Tienda
Una tienda es un objeto que almacena el estado actual de una aplicación Redux. El estado inicial del almacén se crea pasando un reductor a la función configureStore
.
1 |
import { configureStore } from '@reduxjs/toolkit' |
2 |
|
3 |
const store = configureStore({ reducer: counterReducer }) |
4 |
|
5 |
console.log(store.getState()) |
Para obtener el estado actual de una tienda, utiliza la función getState()
como se indica arriba.
Despacho y selectores
dispatch()
es un método de almacenamiento Redux y se utiliza para actualizar el estado pasando un objeto de acción. Aquí, creamos una acción task/taskAdded
con el creador de la acción addTask()
, y luego la pasamos al método dispatch()
.
1 |
store.dispatch(addTask('pick up laundry')) |
Los selectores se utilizan para leer los datos de una tienda.
Tutorial sobre el uso de Redux con Reactact Native
En este tutorial de React Native Redux, desarrollarás una aplicación que permite al usuario elegir entre un determinado conjunto de temas. La aplicación contendrá dos pantallas, y también aprenderás a navegar entre ellas usando react-navigation
.
Crear una nueva aplicación de React
Crear un nuevo proyecto usando la herramienta Expo CLI.
1 |
expo init ReduxApp |
Actualmente, tienes un solo componente, App.js que muestra un mensaje de bienvenida.
Crear dos nuevos componentes en Home.js y Subjects.js. El componente home será la primera pantalla que vea un usuario, y el componente subjects mostrará todos los temas de nuestra aplicación. Copia el código de App.js y añádelo a Home.js y Subjects.js.
Modifica Home.js y Subjects.js para usar Home
y Subjects
en lugar de la clase App
.
1 |
//Home.js |
2 |
|
3 |
import React from 'react'; |
4 |
import { StyleSheet, Text, View } from 'react-native'; |
5 |
|
6 |
class Home extends React.Component { |
7 |
render() { |
8 |
//... |
9 |
} |
10 |
} |
11 |
|
12 |
// ... |
13 |
export default Home; |
Subects.js debe tener un aspecto similar.
Navegando entre las pantallas
Actualmente, no hay forma de navegar entre las dos pantallas. El navegador de la pila permite a tu aplicación pasar de una pantalla a otra donde cada nueva pantalla se coloca en la parte superior de una pila.
Primero, instala @react-navigation/native
y sus dependencias.
1 |
npm install @react-navigation/native
|
Para un proyecto Expo-managed, instala lo siguiente.
1 |
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
|
Ve a App.js e importa react-native-gesture-handler
en la parte superior. También necesitas añadir NavigationContainer
y createStackNavigator
a App.js. Luego, para agregar capacidades de navegación, envuelve los componentes dentro de la clase App
en un componente NavigationContainer
.
1 |
import { NavigationContainer } from '@react-navigation/native'; |
2 |
import { createStackNavigator } from '@react-navigation/stack'; |
3 |
|
4 |
const Stack = createStackNavigator(); |
5 |
|
6 |
// ...
|
7 |
|
8 |
class App extends React.Component { |
9 |
render() { |
10 |
return ( |
11 |
<NavigationContainer> |
12 |
<Stack.Navigator> |
13 |
<Stack.Screen |
14 |
name="Home" |
15 |
component={Home} |
16 |
/> |
17 |
<Stack.Screen |
18 |
name="Subjects" |
19 |
component={Subjects} |
20 |
/> |
21 |
</Stack.Navigator> |
22 |
</NavigationContainer> |
23 |
);
|
24 |
}
|
25 |
}
|
26 |
|
27 |
// ...
|
Ahora el navegador es consciente de tus pantallas, y puedes proporcionar enlaces para la transición entre pantallas.
Redux en una aplicación React Native
Como mencionamos anteriormente, Redux es una herramienta de gestión de estados, y la usarás para gestionar todos los estados de la aplicación. Nuestra aplicación es un selector de temas donde el usuario elige los temas de una lista predefinida.
Primero, instala los paquetes Redux.
1 |
npm install redux react-redux
|
Una aplicación Redux cumple las siguientes condiciones:
- El estado describe completamente la condición de la aplicación en cualquier momento.
- La interfaz de usuario se muestra basada en el estado de la aplicación.
Por ejemplo, cuando un usuario hace clic en un botón, el estado se actualiza, y la interfaz de usuario muestra el cambio basado en el estado.
Crear un reductor
El reductor se encargará de mantener el estado de los subjects en todo momento.
Crea el archivo SubjectsReducer.js en el nivel de la raíz y añade el siguiente código.
1 |
import { combineReducers } from 'redux'; |
2 |
|
3 |
const INITIAL_STATE = { |
4 |
current: [], |
5 |
all_subjects: [ |
6 |
'Literature', |
7 |
'Speech', |
8 |
'Writing', |
9 |
'Algebra', |
10 |
'Geometry', |
11 |
'Statistics', |
12 |
'Chemisrty', |
13 |
'Biology', |
14 |
'Physics', |
15 |
'Economics', |
16 |
'Geography', |
17 |
'History', |
18 |
],
|
19 |
};
|
20 |
|
21 |
const subjectsReducer = (state = INITIAL_STATE, action) => { |
22 |
switch (action.type) { |
23 |
default: |
24 |
return state |
25 |
}
|
26 |
};
|
27 |
|
28 |
export default combineReducers({ |
29 |
subjects: subjectsReducer |
30 |
});
|
En este archivo, se crea una variable INITIAL_STATE
con todas las asignaturas del plan de estudios y se exporta el reductor de asignaturas como una propiedad llamada subjects
. Hasta ahora, el reductor de materias no responde a ninguna acción, el estado no puede cambiar.
Crear una acción
Una acción tiene un tipo y una carga útil opcional. En este caso, el tipo será SELECT_SUBJECT
, y la carga útil será el índice de la matriz de los subjects a seleccionar.
Crea el archivo SubjectsActions.js en el nivel raíz y añade el siguiente código.
1 |
export const addSubject = subjectsIndex => ( |
2 |
{
|
3 |
type: 'SELECT_SUBJECT', |
4 |
payload: subjectsIndex, |
5 |
}
|
6 |
);
|
Ahora, actualizaremos el reductor para responder a esta acción.
1 |
// ...
|
2 |
|
3 |
const subjectsReducer = (state = INITIAL_STATE, action) => { |
4 |
switch (action.type) { |
5 |
case 'SELECT_SUBJECT': |
6 |
|
7 |
// copy the state
|
8 |
const { current, all_subjects,} = state; |
9 |
|
10 |
//remove a subject from the all_subjects array
|
11 |
|
12 |
const addedSubject = all_subjects.splice(action.payload, 1); |
13 |
|
14 |
// put subject in current array
|
15 |
current.push(addedSubject); |
16 |
|
17 |
// update the redux state to reflect the change
|
18 |
const newState = { current, all_subjects }; |
19 |
|
20 |
//return new state
|
21 |
return newState; |
22 |
|
23 |
default: |
24 |
return state |
25 |
}
|
26 |
};
|
27 |
|
28 |
// ...
|
Añadir el reductor a la aplicación
Ahora, abre App.js y crea una nueva tienda para la aplicación usando la función createStore()
. También ponemos ese almacén a disposición de los componentes de nuestra aplicación envolviéndolos en el componente <Provider>
. Esto asegurará que todos los componentes hijos puedan acceder al estado de la tienda.
1 |
import 'react-native-gesture-handler'; |
2 |
import React from 'react'; |
3 |
import { Provider } from 'react-redux'; |
4 |
import { createStore } from 'redux'; |
5 |
import { StyleSheet } from 'react-native'; |
6 |
import { NavigationContainer } from '@react-navigation/native'; |
7 |
import { createStackNavigator } from '@react-navigation/stack'; |
8 |
import subjectsReducer from './SubjectsReducer'; |
9 |
import Home from './Home'; |
10 |
import Subjects from './Subjects'; |
11 |
|
12 |
// ... . rest of the code
|
13 |
|
14 |
const store = createStore(subjectsReducer); |
15 |
|
16 |
class App extends React.Component { |
17 |
// ...
|
18 |
|
19 |
render() { |
20 |
return ( |
21 |
<Provider store={store}> |
22 |
<NavigationContainer> |
23 |
//.. rest of the code
|
24 |
</NavigationContainer> |
25 |
</Provider> |
26 |
)
|
27 |
}
|
28 |
}
|
Añadir Redux a los componentes
Ahora veamos cómo hacer que los datos de estado estén disponibles para los componentes con la función connect()
. Para usar connect()
, necesitamos crear una función mapStateToProps
, la cual mapeará el estado del almacén a los puntales en los dos componentes.
Abre Home.js, mapea el estado, y renderiza los valores para los subjects actuales (que se encontrarán en this.props.subjects.current
). Además, agrega un botón para navegar al componente Subjects
.
1 |
import React from 'react'; |
2 |
import { connect } from 'react-redux'; |
3 |
import { StyleSheet, Text, View, Button } from 'react-native'; |
4 |
|
5 |
class Home extends React.Component { |
6 |
render() { |
7 |
return ( |
8 |
<View style={styles.container}> |
9 |
<Text>You have { this.props.all_subjects.current.length } subjects.</Text> |
10 |
<Button |
11 |
title="Select more subjects" |
12 |
onPress={() => |
13 |
this.props.navigation.navigate('Subjects') |
14 |
}
|
15 |
/> |
16 |
</View> |
17 |
);
|
18 |
}
|
19 |
}
|
20 |
|
21 |
|
22 |
const mapStateToProps = (state) => { |
23 |
const { subjects } = state |
24 |
return { subjects } |
25 |
};
|
26 |
|
27 |
export default connect(mapStateToProps)(Home); |
De manera similar, usaremos connect
en el archivo Subjects.js para mapear el estado a las propiedades del componente.
1 |
import React from 'react'; |
2 |
import { connect } from 'react-redux'; |
3 |
import { StyleSheet, Text, View, Button } from 'react-native'; |
4 |
|
5 |
class Subjects extends React.Component { |
6 |
render() { |
7 |
return ( |
8 |
<View style={styles.container}> |
9 |
<Text>My Subjects!</Text> |
10 |
/>
|
11 |
</View> |
12 |
);
|
13 |
}
|
14 |
}
|
15 |
|
16 |
//...
|
17 |
|
18 |
const mapStateToProps = (state) => { |
19 |
const { subjects } = state |
20 |
return { subjects } |
21 |
};
|
22 |
|
23 |
export default connect(mapStateToProps)(Subjects); |
También añadiremos el código para mostrar todos los subjects en el componente Subjects
y un botón para navegar a la pantalla de inicio. También añadirá un botón que añadirá la acción addSubject
a Subject.js. Aquí está cómo debería verse el método render()
final en Subject.js:
1 |
class Subject extends React.Component { |
2 |
render() { |
3 |
return ( |
4 |
<View style={styles.container}> |
5 |
<Text>Select Subjects Below!</Text> |
6 |
|
7 |
{
|
8 |
this.props.subjects.all_subjects.map((subject, index) => ( |
9 |
<Button |
10 |
key={ subject } |
11 |
title={ `Add ${ subject }` } |
12 |
onPress={() => |
13 |
this.props.addSubject(index) |
14 |
}
|
15 |
/> |
16 |
))
|
17 |
}
|
18 |
|
19 |
<Button |
20 |
title="Back to home" |
21 |
onPress={() => |
22 |
this.props.navigation.navigate('Home') |
23 |
}
|
24 |
/> |
25 |
</View> |
26 |
);
|
27 |
}
|
28 |
}
|
La aplicación final debería verse así.



Conclusión
Redux es una herramienta valiosa, pero solo es útil cuando se usa de la manera correcta. Algunas de las situaciones en las que Redux podría ser útil incluyen código en el que está trabajando mucha gente o aplicaciones que contienen grandes cantidades de estado de aplicación.
En este tutorial, aprendiste a configurar una aplicación de React Native usando Redux.
Las mejores plantillas de aplicaciones de React Native en CodeCanyon
CodeCanyon es un mercado digital que ofrece la mejor colección de temas y plantillas de React Native. Con una plantilla de aplicaciones de React Native, puedes empezar a construir tus aplicaciones en el menor tiempo posible.



Si tienes problemas para decidir qué plantilla de React Native en CodeCanyon es la adecuada para ti, este artículo debería ayudarte: