Okay! but why React.js?

Okay! but why React.js?

ยท

18 min read

Featured on Hashnode

TLDR; A high level overview of what makes React special and why React is great ๐Ÿš€

I have decided to write series of blogs on React, JavaScript, Algorithms, Data Structures and some Firebase services like Firebase Hosting, Cloud Firestore, Authentication and more. So here is the first one ๐Ÿš€

But before we dive into why React, let's start with What?

What is React?

So, React is a open-source JavaScript Library for building user interfaces and single-page applications. It was developed by Facebook. And most important React is the most popular JavaScript UI Library used in the world right now.

React allows developers to create large web applications that can change data, without reloading the page. The main purpose of React is to be fast, scalable, and simple. It works only on user interfaces in the application. To get started, you need the basic understanding of: HTML, CSS & JavaScript ES6.

Okay! That's it about React ๐Ÿฅณ

In this blog, I'm not going talk about React.js syntax, it's functionlity or anything like that but actually I'm going to talk about Why React? Why we should use it? So here are few things that makes React special โœจ

  1. Its compositional model
  2. Its declarative nature
  3. The way data flows through a Component
  4. And that React is really just JavaScript

What is Composition?

Composition basically mean to combine simple functions to build more complicated ones. So let's take a look at how we can build up complex functions just by combining simple ones together.

Now, one of the best part about React is that you can use the same intuitions that you have about functions for when to create React components. If you are familiar with functions then you know that functions are taking some arguments and returning a value. Similarliy in React, your functions is going to take some arguments and return some UI. It's that much simple!

Here is an example of composition which is built from simple functions:

These are two one line simple functions getProfileLink and getProfilePic.

function getProfileLink (username) {
 return 'https://twitter.com/' + username
}

function getProfilePic (username) {
 return 'https://twitter.com/' + username + '.png?size=200'
}

Above are two simple functions, so to compose them, we'd just combine them together inside another function getProfileData:

function getProfileData (username) {
 return {
    pic: getProfilePic(username),
    link: getProfileLink(username)
 }
}

We can also do this without composition by providing the data directly into getProfileData:

function getProfileData (username) {
 return {
 pic: 'https://twitter.com/' + username + '.png?size=200',
 link: 'https://twitter.com/' + username
 }
}

There is nothing wrong in the above without composition code but the good function should follow the "DOT" rule:

Do One Thing

In the composed version, each function just does one thing:

  • getProfileLink โ€“ just builds up a string of the user's Twitter profile link
  • getProfilePic โ€“ just builds up a string the user's Twitter profile picture
  • getProfileData โ€“ returns a new object

Now let's implement the same compositional method in React. We do this in React by composing functions to get some UI. Here is an example:

function ProfileLink (username) {
 return (
    <img
       alt={username}
       src={'https://twitter.com' + username + '.png?size=200'}
    />
    )
}

function ProfileLink (username) {
 return <a href={'https://twitter.com' + username}>{username}</a>
}

function Profile (username) {
  return (
    <div className="profile">
       <ProfilePic username='username' />
       <ProfileLink username='username' />
    </div>
  )
}

The concept of composition is such a large part of what makes React awesome and incredible to work with. React builds up pieces of a UI using components. Let's take a look at some pseudo code for an example. Here are three different components:

<Header />
<Home />
<Sidebar />

Now let's take these simple components, combine them together, and create a more complex component (aka, composition in action!):

<Page>
 <Home />
 <Sidebar />
</Page>

Here the <Page> component has the <Article /> and <Sidebar />components inside. This is just like the earlier example where getProfileData had getProfileLink and getProfilePic inside it. So this is how composition plays a huge part in building React components and make our work easy.

Composition Recap

Composition occurs when simple functions are combined together to create more complex functions. Think of each function as a single building block that does one thing (DOT). When you combine these simple functions together to form a more complex function, this is composition.

What is Declarative Code?

React let you do imperative work for your code. You declare state and markup and react does imperative work of keeping the DOM in sync with your application.

Okay but what imperative mean here:

When we write some JavaScript code imperatively, we tell JavaScript exactly what to do and how to do it. Think of it as if we're giving JavaScript commands on exactly what steps it should take. For example:

const basket = ['Apple', 'Grapes', 'Blueberry', 'Mango', 'Pineapple']
const anotherBasket = []

for (let i = 0; i < basket.length; i++) {
 anotherBasket[i] = basket[i] + '!'
}

If you are familiar with JavaScript, then it is pretty straightforward that we are looping through each items that are present in the basket array, adding an exclamation mark to fruit names, and storing the new string in the anotherBasket array. Pretty simple, right?

This is imperative code, though. We're commanding JavaScript what to do at every single step. We have to give it commands to:

  • set an initial value for the iterator - (let i = 0)
  • tell the for loop when it needs to stop - (i < basket.length)
  • get the basket at the current position and add an exclamation mark - (basket[i] + '!')
  • store the data in the ith position in the other array - (anotherBasket[i])
  • increment the ivariable by one - (i++)

You have to manually do multiple steps. It's not ideal, right? So let's improve things by learning about declarative stuffs!

Declarative Code

With declarative code, we don't code up all of the steps to get us to the end result. Instead, we declare what we want done, and JavaScript will take care of doing it. This explanation is a bit abstract, so let's look at an example. Let's take the imperative for loop code we were just looking at and refactor it to be more declarative.

const basket = ['Apple', 'Grapes', 'Blueberry', 'Mango', 'Pineapple']
const anotherBasket = basket.map(fruit => fruit + '!')

That's it! Notice that with this code we haven't:

  • created an iterator object
  • told the code when it should stop running
  • used the iterator to access a specific item in the basket array
  • stored each new string in the anotherBasket array
  • ...all of those steps are taken care of by JavaScript's .map() Array method.

Declarative Code Recap

Imperative code instructs JavaScript on how it should perform each step. With declarative code, we tell JavaScript what we want to be done, and let JavaScript take care of performing the steps.

React is declarative because we write the code that we want, and React is in charge of taking our declared code and performing all of the JavaScript/DOM steps to get us to our desired result.

What is Unidirectional Data Flow?

Before React, one popular technique for managing state changes in an app over time was to use Data Bindings.

But the one problem with Data Binding is when data changes in one place, that changes automatically reflect in other place in our application. So any part of the app that had that data would also change it. This technique works great with the small application but as the app starts to grow high, this technique makes it difficult to determine how a change in one place automatically and implicitly affects the rest of the app.

React uses an explicit method for passing data between components that makes it a lot easier to track changes to the state and how they affect other places of the app. So, this is called Unidirectional Data Flow because data flows one way only from parents elements down to children elements.

Let me make it clear for you with data flow diagram:

Screenshot 2021-01-06 at 8.45.19 PM.png

So from the above diagram we have two components:

  • a parent component
  • a child component

Data is flowing down from parent component to child component. Data updates are sent to the parent component where the parent performs the actual change.

Let's talk about the above statement in more depth:

The data lives in the parent component and is passed down to the child component. Even though the data lives in the parent component, both the parent and the children components can use that data. However, if the child component needs to make a change to the data, then it would send the updated data to the parent component where the change will actually be made. Once the change is made in the parent component, the child component will be passed the data (that has just been updated!).

Now, this might seem like extra work, but having the data flow in one direction and having one place where the data is modified makes it much easier to understand how the application works.

React is "just JavaScript"

React doesn't like the functionality that you can already do in JavaScript. For example: If you want to create a list of item and shows them to view. Instead of rendering each item manually, in React you can use JavaScript .split() and .map() method to do that.

React builds on a lot of the techniques of functional programming...techniques. However, there are a couple of important JavaScript functions that are vital to functional programming that we should look at. These are the Array's .map() and .filter() methods.

Array's .map() Method

If you're not familiar with JavaScript's Array .map() method, it gets called on an existing array and returns a new array based on what is returned from the function that's passed as an argument. Let's take a look:

const basket = ['Apple', 'Grapes', 'Blueberry', 'Mango', 'Pineapple']
const basketLengths = basket.map( fruit => fruit.length );

Let's go over what's happening here. The .map() method works on arrays, so we have to have an array to start with:

const basket = ['Apple', 'Grapes', 'Blueberry', 'Mango', 'Pineapple']

We call .map() on the basket array and pass it a function as an argument:

basket.map( fruit => fruit.length );

The arrow function that's passed to .map() gets called for each item in the names array! The arrow function receives the first name in the array, stores it in the name variable and returns its length. Then it does that again for the remaining two names.

.map() returns a new array with the values that are returned from the arrow function:

const basketLengths = basket.map( fruit => fruit.length );

So basketLengths will be a new array [5, 6, 9, 5, 9].

This is important to understand the .map() method returns a new array, it does not modify the original array.

Array's .filter() Method

JavaScript's Array .filter() method is similar to the .map() method:

  • it is called on an array
  • it takes a function as an argument
  • it returns a new array

The difference is that the function passed to .filter() is used as a test, and only items in the array that pass the test are included in the new array. Let's take a look at an example:

const basket = ['Apple', 'Grapes', 'Blueberry', 'Mango', 'Pineapple']
const shortBasket = basket.filter( fruit => fruit.length < 6 );

Just as before, we have the starting array. We call .filter() on the fruit names array and pass it a function as an argument:

basket.filter( fruit => fruit.length < 6 );

Again, just like with .map() the arrow function that's passed to .filter() gets called for each item in the basket array. The first item (i.e. 'Apple') is stored in the fruit name variable. Then the test is performed - this is what's doing the actual filtering. It checks the length of the name. If it's 6 or greater, then it's skipped (and not included in the new array!). But if the length of the fruit name is less than 6, then fruit.length < 6 returns true and the name is included in the new array!

const shortBasket = basket.filter( fruit => fruit.length < 6 );

And lastly, just like with .map() the .filter() method returns a new array instead of modifying the original array.

React is Just JavaScript Recap

React builds on what you already know - JavaScript! You don't have to learn a special template library or a new way of doing things.

Two of the main methods that you'll be using quite a lot are:

  • .map()
  • .filter()

It's important that you're comfortable using these methods. Why not to look through some of your existing code and try converting your for loops to .map() calls or see if you can remove any if statements by using .filter().

Bonus ๐Ÿ„

Here is the Bonus part for you, if you have have done reading this:

DOM is stand for Document Object Model. DOM represent the UI of your application. Every time there is a change in the state of your application UI, the DOM gets updated to represent that change.

It is a powerful tree like structure that organize the elements on a web page and allow scripting language to access them.

Resources I use:

  • My old Udacity React notes
  • React official documentation
  • Some of my project work

That's all people ๐ŸŒป Thank you for reading this blog, hoping that you'll find this helpful. This is my first blog here. Please let me know in the comment, if you have learn something from this blog. ๐Ÿ’›