Check out our Angular Book Series.

Learning Redux - Vanilla JavaScript Sample - Part 2

Redux is a state Management Framework that is primarily used with React, but can also be used with Angular. This article series looks at using Redux without another framework. Please read part 1 before reading this.

I write about Redux and Angular in the bonus book to the Angular 6 series.

This article will show you how to write your first Redux application. We're going to create a simple Hello World style sample.

Set up the Infrastructure

Create a new blank HTML Page. It'll look something like this:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Redux Vanilla JS</title>
</head>
<body>
</code>
</body>
</html>

Import the Redux library:


<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js">
</script>

Instead of using NodeJS and Build Script tools, I'm just pulling it out from an Internet based CDN because it is the simplest way. Create the reducer:


<script>
function reducer(state, action) {
}
</script>

The reducer is the function that will run when actions are dispatched to the store. It takes in the current state and the action, then runs code to determine what the new state will be. A reducer should not have any side effects. That means it should not modify the existing state. The first step is to make a copy of the existing state:


var newState = Object.assign({}, state)

On first run of the application, no existing state will be defined, so we'll check for that and set some defaults:


if (typeof state === 'undefined') {
newState = {
helloUser : ''
}
}

The state of the application is just a JavaScript object. I included one property on that object, helloUser and defaulted it to an empty string. Once we start dispatching events, we'll revisit this function to handle those event types. Until then, just return the new state:


return newState;

That completes the reducer, for the moment.

Now, create the store:


var store = Redux.createStore(reducer);

This calls the createStore() value on the Redux library. The reducer() function is passed in. Notice we are saving the store as a local variable for future reference. Do not put this line of code inside the reduce.

Let's create our simple UI:


Enter Your Name: <input id="username"><br/><br/>
Hello <span id="helloValue"></span>

We're going to set this up so that when the user types in the input, the text will automatically update in the span. I've seen similar samples used to demonstrate how binding works in Angular.

Let's switch back to JavaScript and create a function to render the UI:


function renderHello() {
document.getElementById('helloValue').innerHTML =
store.getState().helloUser.toString()
}

The renderHello() function accepts no arguments. It uses the JavaScript document object and getElementByID() function to retrieve the helloValue span. Then it populates it with the helloUser string in the state. We retrieve the state from the store using the getState() functionality. Be sure to call the renderHello() function immediately to render the function in the default state:


renderHello()

Whenever the state changes, we want to run this renderHello() function. We do that with the subscribe() function on the Redux store:


store.subscribe(renderHello)

Now, when the state changes, the renderHello() function will be called, thus causing the UI to update.

Whenever the username input is modified, we want to dispatch an action to the store so that the reducer() function runs, which will return the modified state, and then run the renderHello() listener to modify the UI. This is the code:


document.getElementById('username').addEventListener('keyup', function (e) {
store.dispatch({ type: 'NAME_MODIFIED', value : e.target.value})
})

Without a framework, such as Angular, it is a bit complex to listen for events on elements, but we grab the username input with getElementByID() and then listen for the keyup event. We use store.dispatch() to send a NAME_MODIFIED action. By convention, the type of the action is a constant put in all caps, but here we are hard coding it a bit.

We need to modify the reducer() function to handle the NAME_MODIFIED action:


switch (action.type) {
case 'NAME_MODIFIED':
newState.helloUser = action.value
break;
default:
// do nothing
}

This code is after the undefined check, and before the return statement. It is a switch statement that checks for the action's type, and does actions based on that. At this stage in the application, we only have a single event, but we'll add one more as we iterate over this code.

You should be able to run the code now:

As you type your name the text will appear after the hello.

Play with this sample.

And don't forget to pick up the Angular 6 books from the Learn With series.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.