React for Vue.js Devs: My Experience
Tags: react, vue
Published: 2020-08-02 15:16:12

Recently I was having a look at the online job and internship situation online. Though I started with React, soon Vue.js became my preferred frontend framework. So, when I discovered that most of the online jobs and internships look for React developer, rather than Vue.js developer, I found myself re-learning react from the ground up. Today, in this post I'm going to talk about the points I noticed as a vue.js developer learning react.

> Note: All the comparisons are done here based on the "base code" provided by their individual CLIs. So, the simple component structure by importing scripts is not discussed.

## 0. The CLI:

Both React and Vue.js provide a CLI to set up the projects in an optimal way. In vue.js the CLI takes care of some extra setups like Typescript selection, CSS pre-processor selection, Vuex(state management) setup, Vue Router setup and all that. For doing all those setup in react you need to do it manually separately.

One more advantage of vue CLI over React is that vue CLI also provides a GUI to setup projects.

While the vue CLI being really big it is recommended to install it instead of using it with npx, you can use react CLI with npx directly.

For vue.js you need to install the CLI with this command:

```
npm i -g @vue/cli
```

> Warning: The old vue CLI is known as `vue-cli`. So, if you have that uninstall that and install this new CLI. 

Once installed you can use this CLI to create a new Vue.js application:

```
vue create new-project
```

However, if you don't want to go through all this slow setup process you can use [vite](https://github.com/vitejs/vite) to create vue app in no time, but it is not for production-level apps yet.

```
npm init vite-app test
```

On the other hand, to set up a react project with CLI you can use this command:

```
npx create-react-app test
``` 

Or, you can first install this CLI globally and then use it:

```
npm install -g create-react-app
create-react-app test
```

> **Did you know?** you can use vite for creating react apps quickly as well? Well the command for that will be: 

```
npm init vite-app react-app --template react
```

## 1. The component structure:

In vue.js we generally work with components with `.vue` extension. These files have three parts: 
   
   a. The HTML layout in `<template></template>` part.
   b. The CSS part in `<style></style>` tags.
   c. The logical JavaScript part in `<script></script>` tags.

Example Vue component:

```vue
<template>
  <h1>Hello World</h1>
</template>

<script>
    export default {
        name: "HelloWorld",
        props: {},
        data() {
            return {
                //if any data is required then it is passed here
            }
        },
        methods: {
            //all the required methods go here...
        }
    }
</script>

<style scoped>
    h1 {
        text-align: "center" 
    }
</style>

``` 

While in react we work with components delivered by plain Javascript files, sometimes `.jsx` files. According to the modern react function based component structure, you will need a function returning HTML like markup(JSX) from a JS function. A typical react function based component looks like:

```JS
import react from 'react';

function HelloWorld(props){
   //all the component based state/varibales/data and methods can go here

   return(
      <h1>Hello World</h1>
   )
}

export default HelloWorld;
```

## 2. The HTML/Markup

For any webpage, the most important thing is the markup. In Vue.js you can write your component's markup directly in normal HTML inside the `<template></template>` tags. 

But in React as your component is returned by a JavaScript function via jsx, so there are some small changes:

   a. You can't use `class` and similar reserved words in JavaScipt. So you will need to use some alternatives provided in jsx like `className` instead of `class`
   b. pretty much all the HTML element properties are to be written in "camelCase"

## 3. Dealing with style

In vue.js the style can be defined directly inside the component. It can be written in normal CSS syntax easily the `<style></style>` tags. From here you can easily change the language used for styling(SCSS, LESS etc., if it is configured) or you can simply change the scope of the stylesheet.

In React.js there are two ways to define styles:

a. You can write a CSS in a separate `.css` file and can easily import it in your react component like so:

```JS
import "./app.css"
```

However, this styling is globally applied.

b. You can write CSS as a JavaScript object using JSS

```JSX
import React from "react";
import injectSheet from "react-jss";

const styles = {
  center: {
    textAlign: "center"
  }
};

const HelloWorld = ({ classes }) => (
  <h1 className={classes.center}>
    Hello World
  </h1>
);

const StyledWorld = injectSheet(styles)(HelloWorld);

export default StyledWorld
```

> I avoided the inline CSS part as I don't prefer it as a good method to write CSS 

## 4. Dynamic Variables:

In vue.js the data is normally managed using the data() method where we define a function which returns all of our required data. Then using the `methods` we define the functions we can call later to modify the values of the defined data.

But in react you need to use hooks to define both the required data as well as the main method which need to be called to change that data.

To render the value of these dynamic variables directly in the website in Vue we use the `{{variable name}}` template literal: 

```vue
<template>
  <h1>
    {{requiredVariable}}
  </h1>
</template>

<script>
  export default{
     data(){
        return(
          requiredVariable: "Hello"
        )
     },
     methods: {
        //...
     }
  }
</script>
```


While in React we can do the same by using `{variable_name}` template literal:

```jsx
import React, {useState} from 'react'

function Home() {
  const [requiredVariable, setRequiredVariable] = useState("Hello");

  //any function which might dynamically update the link by calling setRequiredVariable inside it

  return (
    <h1>
      {requiredVariable}
    </h1>
  );
}

export default Home;
```

## 4-a Getting and Passing props to elements

In both vue.js and react the props are generally passed directly to the element. Example (with an element named ChildComponent):

```jsx
<ChildComponent message="Hello" />
```

Now you can also pass any dynamic data from the parent to the child component. For vue.js, that can be easily done by using the `v-bind` or `:` directive. Example:

```vue
<ChildComponent :count="count"/>
```
> Note: Here a data needs to be predefined with the variable name count so that you can bind it.

If you want to do the same thing with react it would look like:

```JSX
<ChildComponent count={count}/>
```
> Note: Similar to the vue.js disclaimer, you need a count variable predefined in your component to be used here

Now, how to receive the props? For that, in vue.js in the export part of the `<script>` we need to define the props key with an object with details of the props received by that element, with the prop type and the prop name. That will look somewhat like this for a component receiving "message" as a prop:

```vue
export default {
  name: "ChildComponent",
  props: {
    count: Number
  },
  data() {
    return {
      //other data for this component
    };
  },
  methods: {
    //methods for this component
  }
};
</script>
```
In react the same thing will be received in a functional component like this:

```jsx
import React from "react";

export default function ChildComponent(props) {
  //this is extracting all the props from the general prop object passed. Here I have used object restructuring for that. This can also be done in the function arguments. 
  const { message } = props;
  return(
    <div>
      <h1>{props.message}</h1>
      {/* The same thing done with the pre extracted variable */}
      <h1>{message}</h1>
    </div>
  )
}
```

> Note: If you are using react route then you get extra information in the props. While using vue.js router you get similar router related information in the special `$route.params` variable. This is important info for doing routing in vue.js and react

## 5 Using Dynamic Variable for HTML Element properties: 

If you want to set HTML element properties like href value of a link or src value of an image element (i.e where you need only one-way data binding, as they can't be directly changed in the frontend) you can use `v-bind` or its shorthand `:` to bind their values to the dynamic data we have in the element. Example:

```vue
<template>
  <div>
    <a v-bind:href="aLinkDynamicallySet">Dynamic link by v-bind</a>
    <a :href="linkDynamicallySet">Dynamic link by :</a>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      // other data
      linkDynamicallySet: "https://dev.to/ayushmanbthakur"
    }
  },
  methods: {
    //required methods
  }
}
</script>
```

If you want to do the same in the react, you can directly use the template syntax. Example:

```jsx
import React, {useState, useEffect} from 'react'

function Home() {
  const [linkDynamicallySet, setLinkDynamicallySet] = useState("https://dev.to/ayushmanbthakur");

  //any function which might dynamically update the link by calling setLinkDynamicallySet inside it

  return (
    <a href={linkDynamicallySet}>Dynamic link</a>
  );
}

export default Home;
```

## 6. Calling the DOM events like "onclick": 

React is different from vue.js in the aspect of calling DOM events like "onclick" and others. While in react you can call any DOM events using their "camelCased" version, in vue.js you can call these events using the `v-on` directive or the shorthand of that i.e `@` to call the methods defined in script on DOM events.

In vue calling an onclick event on a button looks like:

```vue
<button @click="updateNum">click me</button>
```

In react calling onclick event on a button looks like:

```jsx
<button onClick={updateNum}>click me</button>
```

> Here I have presumed all the other functions are defined properly and accordingly

> **Did you know?** In vue.js `v-on` directive you can call .prevent to execute the `e.preventDefault` without dealing with the event object directly in your method

## 7. Handling form input:

In vue.js you can use the already available `v:model` for a direct both way binding to update your predefined "data" easily.

While in react, due to the absence of such directive you need to define how to update your state according to the change of your input field and set the value of the input field according to the state variable.

A simple Vue based form will look like:

```vue
<template>
  <form v-on:submit="sub">
    <input type="email" v-model="email">
    <input type="submit" value="Subscribe" />
  </form>
</template>

<script>
  export default{
     data(){
        return(
          email: ""
        )
     },
     methods: {
        sub(){
           //all the required subtask
        }
     }
  }
</script>
```

Same code in react will look like:

```jsx
import React, { useState } from "react";

export default function App() {
  const [email, setEmail] = useState("");
  
  const sub = (e) => {
    //all required task
  }

  return (
    <div>
      <form onSubmit={(e) => sub(e)}>
        <input 
           type="email" 
           value={email} 
           onChange={(e) => setEmail(e.target.value)} 
        />
        <input type="submit" value="Subscribe" />
      </form>
    </div>
  );
}
```

## Conclusion

Well, this is just the tip of the iceberg. There are a lot of things which I left untouched, most notable among them is state management. I have my very first blog post discussing [redux vs context API](https://dev.to/ayushmanbthakur/redux-vs-context-api-3182). I would like to do a similar post about vuex and redux in a separate post. Until then stay home, and keep coding😉.