Pages

Showing posts with label React. Show all posts
Showing posts with label React. Show all posts

Friday, May 19, 2017

React + MobX - 101 Todo App for beginners - Part 1

This walk-through-tutorial (yet another) is to guide you through the usage of the MobX library, while building a React application.

The application we'll build is a simple Todo App.

The post discusses the following topics:

  1. What is MobX - A very short explanation about what MobX is. 
  2. Why do you need it? - Reasons to consider using MobX.
  3. Why not Redux (another state management library)?
  4. Code tutorial - Part 1 (out of 2)

What is MobX - https://mobx.js.org/

In short - MobX is a state management library.

In "long" - MobX is a JS library that allows you to define "observable" state (/model/your JS Objects) containing your App information.

The library gives you the power to derive any computed model that depends on observables automatically!
As MobX puts it:
Anything that can be derived from the application state, should be derived. Automatically
In aspect to React:
This gives you the power to mutate the state directly by reference from your components without calling React's setState, and triggering render only on the components that need to be re-rendered.

Pretty nifty.

For more about MobX: https://mobx.js.org/

Why do you need it?

First of all, no one said you should use it. There are plenty React based applications that work just fine without MobX.

However, you should consider MobX for the following reasons, that may give you some advantage.
For instance:
  1. Simpler Components - Having a shared state in your App between several components can be cumbersome to share, especially if one component is deeply nested in another component that uses same data.
    It would mean, that you'd need to pass to all the children of the top-most component that state, resulting many components that are on the way passing on that same state, but never using it.
    Components that change state to other components, the state of your application distributed among many components, and other complications.
    With MobX, you can specify for each component the exact props it should use.
  2. Organized state model - Your application state with MobX is mostly organized in one or few objects that hold only the state of your application. That makes it easy to reason about the application's model.
  3. Optimized App - render only components that need to render instead of 

That sounds like I'm trying to "sell" you MobX.
I find it to be a good library for state management (not saying it's the only, check Redux too), despite the "magic" which I dislike in principal in software, and the awkward feeling I get when this reminds me of "two-way-data-binding" stuff (which the industry has a love-hate relationship since the ages of JavaFX, Flex, and probably even earlier libraries and frameworks).

It comes with a small cost of adding a library to your App, and learning how to use it.
If you have a small application, with a very simple model, you might not even need it.


Why not Redux?

In case you don't know Redux, as mentioned on their site is:
"A predictable state container for JavaScript apps."

In other words - it's a state managing library, like MobX is. But different.
The "what" is similar, the "how", a bit different.

So first of all - why not use it instead? 
There's really no good answer for that, and IMO it's a matter of personal style and what you're comfortable with. It does seem to have less "magic" though.
(The "magic" i refer to are the observables in MobX - this is where the MobX fun happens).

Some say that MobX is easier to get started with as there's less code to write.
It supports several (optional) “stores” vs one store in Redux which can be annoying if you already have an existing App and you need to start consolidating all your state to a single place. 
It conforms to a non-FP paradigm, where your state can be mutable (the observable objects in your state).

In any case, I would advise to try Redux before you make your decision.



Code walk-through


Lets get our hands dirty.
We're going to build the Todo App using MobX & React at last.

Step 0: Fork or clone the Git Repo
Go here and fork/clone it: https://github.com/nirgit/todoMobxTutorial

You will now have a skeleton application which is ready and set up, using ES6 with JSX & Webpack.
MobX is also included in the package.json, so you won't need to add it as a dependency.

Go to the project's directory and run from the console / shell:

> npm run start

Now go to http://localhost:8080

Your web page should look like this:




Step 1: Creating a plain React Todo App

Lets create our plain Todo application based on React only.
  1. Stop Webpack watching your changes 
  2. Go to the project's directory and run from the console / shell:
> git checkout step1
> npm install
> npm run start


Re-open http://localhost:8080, you should now see this:

Great!
You now have a functional React Todo app.
You can open the app.js file and see all the code pretty much.
You won't find anything unusual.
Note how the entire state though is stored on the App component, so once we will refactor the code a little bit, we will have to pass in the todos as a prop to the child components, and probably stuff like a callback to toggle the todos "isDone" field, so we can use setState in order to make it work.

Go back to your shell and now, checkout the step1_2 branch.
> git checkout step1_2


Open the App.js file and take a look at the render method.
See the line?
...
<TodoList todos={this.state.todos} toggleDone={this.toggleDone.bind(this)} />
...

Notice how we pass in to the TodoList component the toggleDone callback, which is still defined on the App component.  If you would decide to create Todo components, you'd probably pass on that callback into each of those components.
And so you will have a component which passes a function to a child (TodoList) which does nothing with that function but pass it on to its children, which affect a state that's found on its grand parent.
A bit Messy.
If you'd have this situation in a large scale application, not only it may be confusing, but it could be practically impossible to reason about the full state of your application at any given point in time.

Lets add MobX and see what happens.

Step 2: Adding MobX to our React App

MobX uses a very small set of core API.

@observable
The API's most significant and basis to all the MobX "magic" is the observable function / decoration (function if you decide not to use the decoration syntax from ES Next).
On this post we'll stick with the decoration as it feels (subjective) a cleaner way to declaratively state the fact a piece of data/object is being observed.

@observer
We have an "observable" data, now what?
We need someone to "observe" it, and react to the changes.
MobX being a library in its own right, does not provide an @observer for React Components "OOTB" ("out of the box").
In order to use such @observer we need to use the MobX-React NPM package.
Then we can "decorate" our React Components with an @observer decoration.

The reaction to the changes made to the observable object will result in calling the render method of the React component observing that object. Pretty cool.

Code example:


So every time you will change the bestMovies collection, the render of MovieList component will be triggered.


Stop your app from running if it is, go back to your shell and now, checkout the step2 branch.
> git checkout step2

and run the following to install missing missing NPM pacakges and re-run the app:
> npm install && npm run start


You shouldn't see any visual difference, but open the browser's Console and see what you got:


See how now you get a log print in the console when a component renders.
Try clicking a checkbox, you should get the following prints:

See how now you get only part of the prints?
Lets do a quick analysis:
  1. App Component - renders because its render function is using the isDone flags of the Todos in order to render the Progress Bar.
  2. ProgressBar Component - renders for obvious reasons.
  3. TodoList Component - renders because it passes all of the properties of the Todo objects, including the isDone property when rendering.
    It does that by using the ES6 spread operator (see in the code "{...t}")
  4. The TodoLine Component - A new component created representing the Todo lines, as it makes it clearer to see MobX's benefit.
    Notice how only the TodoLine Component whose line we changed rendered.
    All the rest - stayed the same without getting re-rendered.


You can run the quick following check.
Go to the todoLine.js file and change the following line:
export default observer(TodoLine);

to this line:
export default TodoLine;

See how we omitted the MobX observer?
Now go back to the browser, and try to check the same checkbox as earlier.
Keep your console opened. You should get the following prints:




Hopefully you got something out of this post, as it should give you an idea of what MobX is by now. Stay tuned for Part 2 blog post that will discuss topics like:

  1. Adding Actions and Action Handler
  2. Adding a Provider component
  3. Adding Containers
Or go explore more yourself on https://mobx.js.org/.

Enjoy,





MobX library image
 ReactJS library image


Saturday, May 21, 2016

Typescript, React and Sass - All in one - Skeleton Project built with Webpack

Just recently I had the need to set up a project that included 
Typescript, React, Sass and building it with Webpack, and couldn't find any good up-to-date source on the web for a 
skeleton project to base it on.

So I decided to create my own.

You can check it out (free of course) on my GitHub account:





Saturday, April 18, 2015

Simple Webapp example using Flux with React

If you've been following the latest Front-End news for Web for the past year,
you have probably seen the huge buzz around ReactJS.

Just in case you haven't, you can visit ReactJS on the Facebook Github's page at: https://facebook.github.io/react/ or just Google it and read about it.

So for those of you that do know what React is all about, you may have also heard about Flux.
If you haven't :) I recommend you to read about it a bit
here as well http://facebook.github.io/flux/docs/overview.html

If I have to try and sum it up on one leg, I'd say that Flux is an application architecture for building
big web-apps on the front-end that scale.  - Well, that's pretty vague :)

A main concept regarding this architecture is about a Uni-directional flow where an "Action"
(a Application Event) is triggered by the View part (Your components, which are shown the users),
using a "Dispatcher" (Some kind of an Event Hub) which propagates the Actions
on to the "Stores" (Your application's model), which hold the state (data) of your application,
perform the necessary update and logic, and updates the View back using listeners.

This illustration might help understanding the Flux flow a little better:









Why is Flux a good idea? - There are several reasons, but I will mention only 2 which I think
are the most important.

1. Simple Application Architecture - You can show this diagram to someone who never
heard of Flux before, and explain it in 2 minutes.

2. Scalable - Flux lets you scale. Meaning, it's relatively easy to add new features to
your application, debug it, and keeping it performant.

Why?
There's a really good talk about it by Facebook which is worth watching:


After all that being said, I really wanted to do some basic implementation of Flux myself,
to "feel" how it works. And so I created a very small Repository on Github that implements
Flux which you are welcome to look at and use.

The example code

The application built on top of that is a classic Todo App: https://github.com/nirgit/Flux1

The code uses several 3rd party libraries such as RequireJS and React Templates but even if you are not familiar with RequireJS, or with AMD, my guess is you will still be able to understand how
it works.
React Templates is an amazing 3rd party library that helps you implement the "render" method
of React Components in an HTML like syntax. Totally cool.

Good luck!