¿Cuáles son las diferencias entre Redux y Flux en ReactJS?

Durante la fase de desarrollo de aplicaciones o software, recopilamos los requisitos de los clientes para crear una solución que resuelva el problema de los clientes o negocios. Para resolver problemas nos apoyamos en diferentes tecnologías y patrones de arquitectura. Durante mucho tiempo, los desarrolladores utilizaron el patrón MVC (Model-View-Controller). Como sabemos, cada mes salen al mercado nuevas tecnologías con nuevas características que reemplazan a las anteriores. Entonces, de la misma manera, el equipo de desarrollo de Facebook presenta cambios importantes y lanza el flujo que se convierte en una opción alternativa para la arquitectura MVC. y después de flux, ha habido otro marco que Redux llega al mercado. Analicemos Redux vs Flux en este artículo.

Flux: Flux es la arquitectura de la aplicación o podemos decir la arquitectura de JavaScript que se utiliza para crear aplicaciones web del lado del cliente o la interfaz de usuario para las aplicaciones del cliente. puede comenzar a usar flux sin mucho código nuevo. flux supera los inconvenientes de MVC, como la inestabilidad y la complejidad.

Ejemplo: En este ejemplo, creamos una aplicación de lista TODO. Este ejemplo contiene la funcionalidad que puede agregar una tarea en la lista TODO junto con puede eliminar la lista de tareas.

Paso 1:   Cree una nueva aplicación de reacción usando los siguientes comandos.

devendra@root:~/Desktop$npx create-react-app todoapp
devendra@root:~/Desktop/todoapp$npm install redux react-redux –save  

Paso 2: Cree una estructura de carpetas en su editor de código como se muestra a continuación en la captura de pantalla. Puede crear archivos manualmente o también usando comandos.

Estructura del proyecto:

estructura de carpetas de la aplicación todo

Paso 3 (Acciones): Las acciones son cosas que suceden durante la vigencia de su aplicación. En nuestra aplicación, cuando el usuario haga clic en el botón Crear, se llamará a una función CRAETE_TODO y se agregará una nueva tarea a la lista. La misma función DELETE_TODO  realizará una acción de eliminación cuando se haga clic en el botón Eliminar. Este es un ejemplo del componente Acción.

TodoActions.js

import dispatcher from "../dispatcher";
  
/* Create task function */
export function createTodo(text) {
  dispatcher.dispatch({
    type: "CREATE_TODO",
    text,
  });
}
  
/* Delete task function */
export function deleteTodo(id) {
  dispatcher.dispatch({
    type: "DELETE_TODO",
    id,
  });
}

Paso 4: Despachadores

Piense en Dispatcher como un enrutador. Las acciones se envían al despachador que solicita las devoluciones de llamada correspondientes.

dispatcher.js

import { Dispatcher } from "flux";
  
export default new Dispatcher;

Paso 5 (Almacenar):

Una tienda es un lugar que contiene el estado de la aplicación. Es muy fácil crear una tienda una vez que tienes reductores. Estamos pasando la propiedad de la tienda al elemento del proveedor, que envuelve nuestro componente de ruta.

Javascript

import { EventEmitter } from 'events';
  
import dispatcher from '../dispatcher';
  
class TodoStore extends EventEmitter {
  constructor() {
    super();
  
    this.todos = [
      {
        id: 16561,
        text: 'hello'
      },
      {
        id: 16562,
        text: 'another todo'
      },
    ];
  }
  
  createTodo(text) {
    const id = Date.now();
  
    this.todos.push({
      id,
      text
    });
  
    this.emit('change');
  }
  
  deleteTodo(id){
    this.todos = this.todos.filter((elm)=>{
      return (elm.id != id);
    });
    this.emit('change');
  }
  
  getAll() {
    return this.todos;
  }
  
  handleActions(action) {
    switch (action.type) {
      case 'CREATE_TODO': {
        this.createTodo(action.text);
        break;
      }
      case 'DELETE_TODO': {
        this.deleteTodo(action.id);
        break;
      }
    }
  }
}
  
const todoStore = new TodoStore();
dispatcher.register(todoStore.handleActions.bind(todoStore));
export default todoStore;

Paso 6 (Componente raíz): El componente index.js es el componente raíz de la aplicación. Solo el componente raíz debe ser consciente de una redux. La parte importante a tener en cuenta es la función de conexión que se utiliza para conectar nuestra aplicación de componente raíz a la tienda. Esta función toma una función de selección como argumento. La función de selección toma el estado de la tienda y devuelve los accesorios (visibleTodos) que podemos usar en nuestros componentes.

Todolist.js

import React from 'react';
import Todo from '../components/Todo';
import TodoStore from '../stores/TodoStore.js';
import * as TodoActions from '../actions/TodoActions';
  
export default class Todolist extends React.Component {
  constructor() {
    super();
  
    this.state = {
      todos: TodoStore.getAll(),
    };
    this.inputContent = '';
  }
  
  // We start listening to the store changes
  componentWillMount() {
   TodoStore.on("change", () => {
     this.setState({
       todos: TodoStore.getAll(),
     });
   });
  }
  
  render() {
      
    const TodoComp = this.state.todos.map(todo => {
      return <Todo key={todo.id} {...todo} />;
    });
  
    return (
      <div>
        <h1> GFG Todo list</h1>
        <input type="text" onChange=
          {(evt)=>this.inputContent = evt.target.value} />
        <button onClick={() => TodoActions
          .createTodo(this.inputContent)}>Create!</button>
        <ul>{TodoComp}</ul>
      </div>
    );
  }
}

Paso 7: Ahora eliminaremos el componente de la tarea.

Todo.js

import React from "react";
import * as TodoActions from '../actions/TodoActions';
  
export default class Todo extends React.Component{
    
  render(){
    return(
      <li>
          <span>{this.props.text}</span>
        <button onClick={()=>TodoActions
          .deleteTodo(this.props.id)}>delete</button>
      </li>
         
    ); 
  }
}

Paso 8: Otros componentes 

index.js

import React from 'react';
import { render } from 'react-dom';
import Todolist from './pages/Todolist';
  
const app = document.getElementById('root');
  
// render(React.createElement(Layout), app);
render(<Todolist />, app);

Paso para ejecutar la aplicación: Abra la terminal y escriba el siguiente comando.

npm start

Salida: el botón Crear agregará una tarea a la lista de tareas pendientes, de manera similar, el botón Eliminar elimina la tarea de la lista de tareas pendientes

Redux: Redux es un contenedor de estado predecible para aplicaciones de JavaScript. Dan Abramov y Andrew Clark desarrollaron Redux en 2015. La propia biblioteca de Redux se puede usar con cualquier capa o marco de interfaz de usuario, incluidos React, Angular, Ember y Vanilla JS. Redux se puede usar con React. ambos son independientes el uno del otro. Redux es una biblioteca de gestión de estado utilizada en aplicaciones de JavaScript. Simplemente administra el estado de su aplicación o, en otras palabras, se utiliza para administrar los datos de la aplicación. Se usa con una biblioteca como React.

Ejemplo: Ahora veremos un contador de ejemplo simple usando react-redux. En este ejemplo, almacenamos un estado de clics de botón y usamos ese estado para hacer clic en otros botones, por ejemplo, creamos cuatro botones de incremento (+), decremento (-), incremento si es impar, incremento asíncrono. 

  • incremento (+), decremento (-): estos dos botones incrementarán el clic en +1 y -1
  • incrementar si es impar: este botón solo incrementará el clic si los dos botones anteriores (+) y (-) el clic es impar, es decir, si el clic es 7, solo este botón aumentará en +1 y ahora los clics serán 8; de lo contrario, esto no aumentará si los botones anteriores (+) y (-) los clics fueron 6 porque 6 es par y se incrementa si el botón impar solo hace clic cuando el estado anterior es un clic impar.
  • incrementar asíncrono: este botón incrementará el clic después de detener o esperar de 1000 mili. segundo.

A continuación se muestra la implementación paso a paso:

Paso 1: Cree una nueva aplicación de reacción usando los siguientes comandos.

npx create-react-app counterproject
npm install redux react-redux --save

Paso 2: cree todos los archivos y carpetas necesarios.

Estructura del proyecto: Tendrá el siguiente aspecto.

archivos y carpetas

Paso 3: Counter.js es un componente de presentación, que se ocupa de cómo se ven las cosas, como el marcado y los estilos. Recibe datos e invoca devoluciones de llamada exclusivamente a través de accesorios. No sabe de dónde provienen los datos ni cómo cambiarlos. Sólo rinde lo que se les da. Este es el componente raíz del contador para representar todo en la interfaz de usuario.

Counter.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'
  
class Counter extends Component {
  constructor(props) {
    super(props);
    this.incrementAsync = this.incrementAsync.bind(this);
    this.incrementIfOdd = this.incrementIfOdd.bind(this);
  }
  
  incrementIfOdd() {
    if (this.props.value % 2 !== 0) {
      this.props.onIncrement()
    }
  }
  
  incrementAsync() {
    setTimeout(this.props.onIncrement, 1000)
  }
  
  render() {
    const { value, onIncrement, onDecrement } = this.props
    return (
        
      <p>
        <h1>GeeksForGeeks Counter Example</h1>
        Clicked: {value} times
        {' '}
        <button onClick={onIncrement}>
          +
        </button>
        {' '}
        <button onClick={onDecrement}>
          -
        </button>
        {' '}
        <button onClick={this.incrementIfOdd}>
          Increment if odd
        </button>
        {' '}
        <button onClick={this.incrementAsync}>
          Increment async
        </button>
      </p>
    )
  }
}
  
Counter.propTypes = {
  value: PropTypes.number.isRequired,
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired
}
  
export default Counter

Paso 4: Counter.spec.js contiene qué cambiar cuando se hace clic en determinados botones de componentes.

Counter.spec.js

import React from 'react'
import { shallow } from 'enzyme'
import Counter from './Counter'
  
function setup(value = 0) {
  const actions = {
    onIncrement: jest.fn(),
    onDecrement: jest.fn()
  }
  const component = shallow(
    <Counter value={value} {...actions} />
  )
  
  return {
    component: component,
    actions: actions,
    buttons: component.find('button'),
    p: component.find('p')
  }
}
  
describe('Counter component', () => {
  it('should display count', () => {
    const { p } = setup()
    expect(p.text()).toMatch(/^Clicked: 0 times/)
  })
  
  it('first button should call onIncrement', () => {
    const { buttons, actions } = setup()
    buttons.at(0).simulate('click')
    expect(actions.onIncrement).toBeCalled()
  })
  
  it('second button should call onDecrement', () => {
    const { buttons, actions } = setup()
    buttons.at(1).simulate('click')
    expect(actions.onDecrement).toBeCalled()
  })
  
  it('third button should not call onIncrement if the counter is even', () => {
    const { buttons, actions } = setup(42)
    buttons.at(2).simulate('click')
    expect(actions.onIncrement).not.toBeCalled()
  })
  
  it('third button should call onIncrement if the counter is odd', () => {
    const { buttons, actions } = setup(43)
    buttons.at(2).simulate('click')
    expect(actions.onIncrement).toBeCalled()
  })
  
  it('third button should call onIncrement if the counter is
    odd and negative', () => {
    const { buttons, actions } = setup(-43)
    buttons.at(2).simulate('click')
    expect(actions.onIncrement).toBeCalled()
  })
  
  it('fourth button should call onIncrement in a second', (done) => {
    const { buttons, actions } = setup()
    buttons.at(3).simulate('click')
    setTimeout(() => {
      expect(actions.onIncrement).toBeCalled()
      done()
    }, 1000)
  })
})

Paso 4: Reductores 

Este es un reductor, una función que toma un valor de estado actual y un objeto de acción que describe «lo que sucedió», y devuelve un nuevo valor de estado. La firma de la función de un reductor es: (estado, acción) => nuevoEstado. significa que una función reductora toma dos parámetros estado y acción . El estado Redux debe contener solo objetos, arrays y primitivos JS simples. El valor del estado raíz suele ser un objeto. Es importante que no mute el objeto de estado, sino que devuelva un nuevo objeto si el estado cambia. Puede usar cualquier lógica condicional que desee en un reductor. En este ejemplo, usamos una declaración de cambio, pero no es necesaria.

index.js

export default (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

Index.spec.js

import counter from './index'
  
describe('reducers', () => {
  describe('counter', () => {
    it('should provide the initial state', () => {
      expect(counter(undefined, {})).toBe(0)
    })
  
    it('should handle INCREMENT action', () => {
      expect(counter(1, { type: 'INCREMENT' })).toBe(2)
    })
  
    it('should handle DECREMENT action', () => {
      expect(counter(1, { type: 'DECREMENT' })).toBe(0)
    })
  
    it('should ignore unknown actions', () => {
      expect(counter(1, { type: 'unknown' })).toBe(1)
    })
  })
})

Paso 5: Tienda

Todos los componentes del contenedor necesitan acceso a Redux Store para suscribirse. Para esto, debemos pasarlo (almacenar) como accesorio a cada componente del contenedor. Sin embargo, se vuelve tedioso. Por lo tanto, recomendamos usar un componente especial llamado React Redux que hace que la tienda esté disponible para todos los componentes del contenedor sin pasarlo explícitamente. Se usa una vez cuando renderiza el componente raíz.

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import Counter from './components/Counter'
import counter from './reducers'
  
const store = createStore(counter)
const rootEl = document.getElementById('root')
  
const render = () => ReactDOM.render(
  <Counter
    value={store.getState()}
    onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
    onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
  />,
  rootEl
)
  
render()
store.subscribe(render)

Paso para ejecutar la aplicación: Abra la terminal y escriba el siguiente comando.

npm start

Producción:

Diferencia entre Redux y Flux: 

No Señor  redux  Flujo
1. Fue desarrollado por Dan Abramov y Andrew Clark. Fue desarrollado por Facebook.
2.  Es una biblioteca JavaScript de código abierto que se utiliza para crear la interfaz de usuario. Es una arquitectura de aplicaciones diseñada para crear aplicaciones web del lado del cliente.
3.

Redux tiene principalmente dos componentes  

  • Creador de acciones
  • Tienda

Flux tiene cuatro componentes principales:

  • Acción
  • Despachador
  • Tienda
  • Vista
4. Redux no tiene ningún despachador. Flux tiene un único despachador.
5.  Redux tiene una sola tienda en la aplicación. Flux tiene varias tiendas en una sola aplicación.
6.  En Redux, las lógicas de datos están en los reductores.  En flujo, la lógica de datos está almacenada.
7.  En el estado de la tienda Redux no se puede cambiar El estado de la tienda In flux puede ser mutable.
8.

Publicación traducida automáticamente

Artículo escrito por devendrasalunke y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *