Advertisement
  1. Code
  2. React Native

Usar Redux en una aplicación de React Native

Scroll to top
Read Time: 10 min

Spanish (Español) translation by Esther (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í.

redux appredux appredux app

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.

React Native app templatesReact Native app templatesReact Native app templates

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

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.