Stuck On is a simple work status feed. It asks you for your work status and displays it in a feed along with your colleagues’ statuses.

For building “Stuck On”, we will be using ReactJS and appbase.io.

ReactJS is a great library choice for building UI views, especially for a project like Stuck On that is simple by design. I encourage you to check out the why react page for good reasons to pick the library. appbase.io is a hosted database API with native support for continuous queries, a good choice for building realtime feeds.

Setup and Code Structure

stuckon-clone/

|_ _ _ _ js/

| |_ _ _ _ StuckOnInput.jsx

| |_ _ _ _ StuckOnFeed.jsx

|_ _ _ _ css/

| |_ _ _ _ style.css

|_ _ _ _ index.html

|_ _ _ _ config.json

The above shows how our final directory structure would look. Let’s initialize all these files for later ease of access.

touch index.html

touch config.json

mkdir -p js && touch js/StuckOnInput.jsx

touch js/StuckOnFeed.jsx

mkdir -p css && touch css/style.css

If you are wondering about the .jsx files in the js/ folder, they are an extension of javascript used by React. A .jsx file allows adding HTML markup for DOM rendering but without altering any of the existing javascript semantics.

Next, we will install react and appbase.io’s js lib via bower.

bower install react

bower install appbase-js

We are all set to write some React now. For keeping the tutorial dead simple, we will break the whole app into two separate pieces — One for posting new status updates and, and the other for viewing the realtime status feed.

Posting New Status Updates

Let’s start by creating a basic HTML skeleton for the app.

Next, we will include the stylesheets (materialize) and javascript files in the HTML. It’s generally a good practice to load the stylesheets first, so we will put them in the <head> element after L3 in the above snippet. All the JS scripts should below the L7. Below are the files to add.

Notice L13,14 above refer to type of .jsx files as “text/babel”. This is because we use the babel transpiler (see L8) to transform .jsx syntax into .js because browser’s javascript runtime can’t understand .jsx (at least, not yet :-)).

Building the component to post a status

Now we will add a div for rendering the status update text inside the container div we created above as shown in the snippet here.

If you are following so far, we’re all set with the html. The snippets above have been numbered as index#{1,2,3}.html to show that we are editing the index.html in a continuing sequence. We will use this notation later for our .jsx files as well.

config.json

Next, we will populate our config.json file with appbase.io app credentials.

You need to get the username and password fields for your app as highlighted above.

We will add the appname along with it’s username and password credentials in the config.json file as shown below. We will additionally set the type field to a string value (say “feed”), and use this for indexing all the status updates.

StuckOn app’s config data for creating a realtime feed

We’re all set with the config.json. If you are using a .git like version control tool, it’s a good idea to add this file to .gitignore, we don’t want other people prying into our app’s credentials.

Now let’s write some .jsx, one method at a time. We will start with the StuckOnInput.jsx file. StuckOnInput contains the StuckOnInput component, which contains two child components — TwitterHandle and StatusInput.

StuckOnInput component (the main UI widget)

|

|_ _ _ _TwitterHandle component (sets user's twitter handle)

|

|_ _ _ _StatusInput component (set's user's work status)

If you aren’t familiar with React components, they are the fundamental units of organizing a React code and are roughly analogous to UI widgets. Components can be inherited, remixed, or contain other components.

We will start with defining the StuckOnInput component, followed by TwitterHandle and StatusInput components. A component in React is always invoked with a React.createClass({specObj}), where the specification object should contain a mandatory render() method. It can contain other methods for initialization and specifying state changes when the user interacts with the DOM. You can read in depth about a component’s spec and lifecycle here.

We will be using the following methods for our StuckOnInput component.

getInitialState is invoked once before the component is mounted. Here, we set up an initial environment for the app.

L11–20 reads the config.json and creates an appbaseRef object, we will use this object later to update the user status to the DB.

L24–32 checks for existing status value from localstorage or sets a default status of “Mining Bitcoin”.

L33–36 returns status and twitterHandle variables, they are set as the initial values for our component’s state.

Next, we will add the componentDidUpdate method.

Similar to how we suffixed the html continuation for the index file, we will suffix each component function as StuckOnInput#method_name.jsx.

componentDidUpdate is invoked every time the component’s updates are rendered on the DOM. We use this method to mirror the state change onto localStorage so we can populate changes in placeholders in the next cycle.

In addInputToAppbase method, we index the status details in Appbase. It is invoked by the StatusInput component when user updates her status. We first call the setState to set the status and then use Appbase to index the status and twitterHandle along with a timestamp field as a JSON object.

setTwitterHandle method is invoked by the TwitterInput component when user enters her twitter handle.

Finally, we render both the status and twitter handle in the render() method of the StuckOnInput component.

Inside render(), we render the status input on the DOM if the user’s twitter handle is set, else we render the twitter input (asking the user to enter their twitter handle) on the DOM. The onSubmit prop in the return condition for both the TwitterInput and StatusInput components is called from these components to invoke the addInputToAppbase and setTwitterHandle methods we declared above.

So far so good. We will complete the status posting functionality by defining the TwitterInput and StatusInput components in the same file (StuckOnInput.jsx).

TwitterInput component takes the twitter handle as an input which onSubmit calls the parent component, the StuckOnInput method, to add the twitter handle. Some important things to note:

Unlike StuckOnInput, we won’t define a getInitialState() method for TwitterInput as it doesn’t have any state.

method for TwitterInput as it doesn’t have any state. We access the <input> tag’s value in L10 using this.refs.nameInput.value . Any DOM element can be accessed in React by adding a ref attribute, we did this for input in L17 as ref=“nameInput”.

. Any DOM element can be accessed in React by adding a ref attribute, we did this for input in L17 as ref=“nameInput”. Calling this.props.onSubmit(value) invokes the setTwitterHandle method in the StuckOnInput component.

Next, we will add the StatusInput component.

StatusInput component takes status as input from the user (L17) calls the StuckOnInput’s addInputToAppbase() method via props.onSubmit in L9. Setting props is a standard way to communicate between components in React.

Last, we will call the global ReactDOM.render() method adding the StuckOnInput component we created above inside the stuckOnInput div defined in the HTML.

We’re ready to render all this on the browser. It looks something like this:

First Screen of “stuck on” app

If you are wondering why it looks so bland, let’s add some styles to our style.css file:

After the styles, our page should look something like below: