Remember how we always say that programming is like Taco Bell? It’s always the same ingredients, except differently! In this particular case, we are going to be relying heavily on Events to create our entire application architecture.
We know you are still in the process of learning React. States and props can be confusing, and now, with Flux, things are going to get a little bit harder. But it’s for a good cause!
Without Flux, you can’t create medium or big React applications because everything will become disorganized pretty quickly.
Also, two different views are not able to send data between each other like the components do (using props) because all views are siblings and React Router is instantiating them. We need to have a common store shared between all the views that we are going to call "The Store."
Here is a list of all the advantages of using it:
Views (Components) | Every React Component that calls any Flux action is called a view. The reason to call those components differently is that React components are supposed to communicate with each other through their props (without Flux). Once a React Component is hard-coded to Flux, you will not be able to reuse that component in the future (on this or any other development). |
Actions | Actions can be triggered components (when the user clicks or interacts with the application) or by the system (for example, the auto-save functionality). Actions are the first step of any Flux workflow, and they always need to dispatch to the store. |
Store | The store contains all the application data. It handles everything incoming from the dispatcher and determines the way data should be stored and retrieved. |
The following project is a To-Do List application with 2 main user stories:
To code the delete functionality, we have to update these files: (1) The Component (for when the user clicks on the track), (2) The Actions, (3) The Store (two times), and (4) The Component one last time. It's only 3 files and 5 updates. And you have to do that for every user story that you are going to build into your application.
In the end, working with Flux has to become something as automatic as riding a bike.
(It’s always a typical JS event like click, hover, resize, etc.)
Everything starts whenever the user clicks on the trash can icon. That is why we need to start our application by listening to the typical onClick event on the delete button.
1// In the component that renders each to-do item we need to add a button and also an onClick listener that calls 2// the respective TodoAction.deleteTodo(task) function that we will create on the actions: 3 4<button onClick={()=>MyActions.deleteTodo(taskToDelete)}>delete</button>
1MyActions.js 2 3// In this case, we decided that this function (a.k.a action) will receive the ID of the task to be deleted. 4class MyActions extends Flux.Actions{ 5 deleteTask(taskToDelete){ 6 // Get the current list of actions from the store 7 let currentActions = MyStore.getActions(); 8 let updatedActions = currentActions.filter((task) => { 9 return (task.id != taskToDelete.id); 10 }); 11 12 this.dispatch('MyStore.setActions', updatedActions); 13 } 14}
☝ This is a class component. We strongly recommend you to use functional components and hooks instead because class components are legacy.
1// Inside the todoStore we have a HandleActions method that contains the logic to handle each dispatched action 2// We have to add a new case to the switch with the name 'DELETE_TODO' 3// It has to match the name of the action that was dispatched 4 5handleActions(action) { 6 switch (action.type) { 7 ... 8 case 'DELETE_TODO': { 9 this.deleteTodo(action.id); 10 break; 11 } 12 } 13}
1 2// Anywhere on your TodoStore class, add a new method that finally deletes the task from the todo list. 3// In this case we are using the filter function because it returns the same array but only with 4// the elements that match the logical question inside the filter (task.id != id) 5 6class TodoStore extends EventEmitter { 7 ... 8 deleteTodo(id){ 9 this.todos = this.todos.filter((task)=>{ 10 // Filter all tasks that have the given id 11 return (task.id != id); 12 }); 13 this.emit('change'); 14 } 15 ... 16}
☝ This is a class component. We strongly recommend you to use functional components and hooks instead because class components are legacy.
Finally, we have a new functionality implemented into our project. To keep adding more functionalities, you just have to start the Flux coding workflow from step 1 all over again.