JavaScript Modules, Router, and Reducer

MODULES:

Allow us to share code between files, you can think about modules as the equivalent of const for our variables but for our javaScript files.

We isolated our js functionally into separate files and modules help us with keeping each bit of our app clearly define from each other.

Then we use the import/export keyword, which helps us to import functionality from other modules, and export labels variables and functions that can be accessed from outside of the current module.

So now in your HTML file, at the end of the body tag, call the script with the source index.js and the type module.

Then lets export a function, in this case, one function and a variable:

And now let's import those in our index.js and that's it!!

If you have a larger function to import you can use export default instead of just export, and then when importing you don’t need the curly braces.

ROUTER:

In Vanilla JavaScript routers could be complicated but they are libraries like Navigo that makes life easier, to install you can drop the following in your index.html file:

or you just can installed via npm/yarn:

then create a new file called router.js follow this example:

REDUCER:

Reducers are used to manage application state in most of the frameworks and libraries like React, Vue, and Angular, and especially in state management libraries like Redux or NgRx.

Reduce is a JS function that takes two arguments, the previous state, and action, and returns, base on this argument a new state:

(state, action) => newState

Reducers are special because they are predictable, they are pure functions, this is a concept from functional programming, that is going to return what it is expected to return.

In this counter, example, we are going to set the count(state) to increase by one, and that's what is going to return, sound redundant but this is the basis of pure functions:

But what about if we want to decrease the count, here is where action came into play, an action is an object that had a key of “type” and the value of the action name, which is a string in uppercase by convention.

type: “DECREMENT”

now for this to work, we have to add some additional logic, to update state accordantly to the type, we can use the if statement but we may have a bunch of conditions, that why the switch/case statement is a better fit.

Let’s run the code, and we can see that we have the expected values.

In case we pass an action that doesn’t exist, after the last case we just default to return state, so the code will run anyway.

but here we have a problem managing the state, reducer is a pure function so we do not have to mutate state directly, what we can do is in every case return an object, and make count part of state, state can have more variables now, like so:

now our reducer does not have side effects, is a pure function.

For more complex examples, we can use another property of action, which is payload, and we can return an object for the payload so we can have more properties in it. In an example of a user with an email, we can do this:

remember when return the object, always use the spread operator, to first return whatever state has, and just then the new state.

for testing again let say that we already have a user initial state in our app, and we want to update it, so first we define the initial user state, and then we just call our userReducer with the action type and action payload that we want to change.

Flatiron Student