I created the exact same app in React and Vue. Here are the differences.
2020 Edition: Now with React Hooks vs Vue 3 + Composition API!
Sunil Sandhu - 28th Jul, 2020
2020 Edition: Now with React Hooks vs Vue 3 + Composition API!
Sunil Sandhu - 28th Jul, 2020
[SHOWTOGROUPS=4,20,22]
A few years ago, I decided to try and build a fairly standard To Do App in React and Vue. Both apps were built using the default CLIs (create-react-app for React, and vue-cli for Vue). My aim was to write something that was unbiased and simply provided a snapshot of how you would perform certain tasks with both technologies.
When React Hooks were released, I followed up the original article with a 'Для просмотра ссылки Войдиили Зарегистрируйся' which replaced the use of Class Components with Functional Hooks. With the release of Vue version 3 and its Composition API, now is the time to one again update this article with a '2020 Edition'.
Let’s take a quick look at how the two apps look:
The CSS code for both apps are exactly the same, but there are differences in where these are located. With that in mind, let’s next have a look at the file structure of both apps:
You’ll see that their structures are similar as well. The key difference so far is that the React app has two CSS files, whereas the Vue app doesn’t have any. The reason for this is because create-react-app creates its default React components with a separate CSS file for its styles, whereas Vue CLI creates single files that contain HTML, CSS, and JavaScript for its default Vue components.
Ultimately, they both achieve the same thing, and there is nothing to say that you can’t go ahead and structure your files differently in React or Vue. It really comes down to personal preference. You will hear plenty of discussion from the dev community over how CSS should be structured, especially with regard to React, as there are a number of CSS-in-JS solutions such as styled-components, and emotion. CSS-in-JS is literally what it sounds like by the way. While these are useful, for now, we will just follow the structure laid out in both CLIs.
But before we go any further, let’s take a quick look at what a typical Vue and React component look like:
A typical React file:
A typical Vue file:
Now that’s out of the way, let’s get into the nitty gritty detail!
How do we mutate data?
But first, what do we even mean by “mutate data”? Sounds a bit technical doesn’t it? It basically just means changing the data that we have stored. So if we wanted to change the value of a person’s name from John to Mark, we would be ‘mutating the data’. So this is where a key difference between React and Vue lies. While Vue essentially creates a data object, where data can freely be updated, React handles this through what is known as a state hook.
Let’s take a look at the set up for both in the images below, then we will explain what is going on after:
React state:
Vue state:
So you can see that we have passed the same data into both, but the structure is a bit different.
With React — or at least since 2019 — we would typically handle state through a series of Hooks. These might look a bit strange at first if you haven’t seen this type of concept before. Basically, it works as follows:
Let’s say we want to create a list of todos. We would likely need to create a variable called list and it would likely take an array of either strings or maybe objects (if say we want to give each todo string an ID and maybe some other things. We would set this up by writing const [list, setList] = useState([]). Here we are using what React calls a Hook — called useState. This basically lets us keep local state within our components.
Also, you may have noticed that we passed in an empty array [] inside of useState(). What we put inside there is what we want list to initially be set to, which in our case, we want to be an empty array. However, you will see from the image above that we passed in some data inside of the array, which ends up being the initialised data for list. Wondering what setList does? There will be more on this later!
In Vue, you would typically place all of your mutable data for a component inside of a setup() function that returns an object with the data and functions you want to expose (which basically just means the things you want to be able to make available for use in your app). You will notice that each piece of state (aka the data we want to be able to mutate) data in our app is wrapped inside of a ref() function. This ref() function is something that we import from Vue and makes it possible for our app to update whenever any of those pieces of data are changed/updated. In short, if you want to make mutable data in Vue, assign a variable to the ref() function and place any default data inside of it.
So how would we reference mutable data in our app?
Well, let’s say that we have some piece of data called name that has been assigned a value of Sunil.
In React, as we have our smaller pieces of state that we created with useState(), it is likely that we would have created something along the lines of const [name, setName] = useState('Sunil'). In our app, we would reference the same piece of data by calling simply calling name. Now the key difference here is that we cannot simply write name = 'John', because React has restrictions in place to prevent this kind of easy, care-free mutation-making. So in React, we would write setName('John'). This is where the setName bit comes into play. Basically, in const [name, setName] = useState('Sunil'), it creates two variables, one which becomes const name = 'Sunil', while the second const setName is assigned a function that enables name to be recreated with a new value.
In Vue, this would be sitting inside of the setup() function and would have been called const name = ref(‘Sunil'). In our app, we would reference this by calling name.value. With Vue, if we want to use the value created inside of a ref() function, we look for .value on the variable rather than simply calling the variable. In other words, if we want the value of a variable that holds state, we look for name.value, not name. If you want to update the value of name, you would do so by updating name.value. For example, let's say that I want to change my name from Sunil to John. I'd do this by writing name.value = "John". I’m not sure how I feel about being called John, but hey ho, things happen!
Effectively React and Vue are doing the same thing here, which is creating data that can be updated. Vue essentially combines its own version of name and setName by default whenever a piece of data wrappeed inside of a ref() function gets updated. React requires that you call setName() with the value inside in order to update state, Vue makes an assumption that you’d want to do this if you were ever trying to update values inside the data object. So Why does React even bother with separating the value from the function, and why is useState() even needed? Essentially, React wants to be able to re-run certain life cycle hooks whenever state changes. In our example, if setName() is called, React will know that some state has changed and can, therefore, run those lifecycle hooks. If you directly mutated state, React would have to do more work to keep track of changes and what lifecycle hooks to run etc.
Now that we have mutations out of the way, let’s get into the nitty, gritty by looking at how we would go about adding new items to both of our To Do Apps.
[/SHOWTOGROUPS]
A few years ago, I decided to try and build a fairly standard To Do App in React and Vue. Both apps were built using the default CLIs (create-react-app for React, and vue-cli for Vue). My aim was to write something that was unbiased and simply provided a snapshot of how you would perform certain tasks with both technologies.
When React Hooks were released, I followed up the original article with a 'Для просмотра ссылки Войди
Let’s take a quick look at how the two apps look:
The CSS code for both apps are exactly the same, but there are differences in where these are located. With that in mind, let’s next have a look at the file structure of both apps:
You’ll see that their structures are similar as well. The key difference so far is that the React app has two CSS files, whereas the Vue app doesn’t have any. The reason for this is because create-react-app creates its default React components with a separate CSS file for its styles, whereas Vue CLI creates single files that contain HTML, CSS, and JavaScript for its default Vue components.
Ultimately, they both achieve the same thing, and there is nothing to say that you can’t go ahead and structure your files differently in React or Vue. It really comes down to personal preference. You will hear plenty of discussion from the dev community over how CSS should be structured, especially with regard to React, as there are a number of CSS-in-JS solutions such as styled-components, and emotion. CSS-in-JS is literally what it sounds like by the way. While these are useful, for now, we will just follow the structure laid out in both CLIs.
But before we go any further, let’s take a quick look at what a typical Vue and React component look like:
A typical React file:
A typical Vue file:
Now that’s out of the way, let’s get into the nitty gritty detail!
How do we mutate data?
But first, what do we even mean by “mutate data”? Sounds a bit technical doesn’t it? It basically just means changing the data that we have stored. So if we wanted to change the value of a person’s name from John to Mark, we would be ‘mutating the data’. So this is where a key difference between React and Vue lies. While Vue essentially creates a data object, where data can freely be updated, React handles this through what is known as a state hook.
Let’s take a look at the set up for both in the images below, then we will explain what is going on after:
React state:
Vue state:
So you can see that we have passed the same data into both, but the structure is a bit different.
With React — or at least since 2019 — we would typically handle state through a series of Hooks. These might look a bit strange at first if you haven’t seen this type of concept before. Basically, it works as follows:
Let’s say we want to create a list of todos. We would likely need to create a variable called list and it would likely take an array of either strings or maybe objects (if say we want to give each todo string an ID and maybe some other things. We would set this up by writing const [list, setList] = useState([]). Here we are using what React calls a Hook — called useState. This basically lets us keep local state within our components.
Also, you may have noticed that we passed in an empty array [] inside of useState(). What we put inside there is what we want list to initially be set to, which in our case, we want to be an empty array. However, you will see from the image above that we passed in some data inside of the array, which ends up being the initialised data for list. Wondering what setList does? There will be more on this later!
In Vue, you would typically place all of your mutable data for a component inside of a setup() function that returns an object with the data and functions you want to expose (which basically just means the things you want to be able to make available for use in your app). You will notice that each piece of state (aka the data we want to be able to mutate) data in our app is wrapped inside of a ref() function. This ref() function is something that we import from Vue and makes it possible for our app to update whenever any of those pieces of data are changed/updated. In short, if you want to make mutable data in Vue, assign a variable to the ref() function and place any default data inside of it.
So how would we reference mutable data in our app?
Well, let’s say that we have some piece of data called name that has been assigned a value of Sunil.
In React, as we have our smaller pieces of state that we created with useState(), it is likely that we would have created something along the lines of const [name, setName] = useState('Sunil'). In our app, we would reference the same piece of data by calling simply calling name. Now the key difference here is that we cannot simply write name = 'John', because React has restrictions in place to prevent this kind of easy, care-free mutation-making. So in React, we would write setName('John'). This is where the setName bit comes into play. Basically, in const [name, setName] = useState('Sunil'), it creates two variables, one which becomes const name = 'Sunil', while the second const setName is assigned a function that enables name to be recreated with a new value.
In Vue, this would be sitting inside of the setup() function and would have been called const name = ref(‘Sunil'). In our app, we would reference this by calling name.value. With Vue, if we want to use the value created inside of a ref() function, we look for .value on the variable rather than simply calling the variable. In other words, if we want the value of a variable that holds state, we look for name.value, not name. If you want to update the value of name, you would do so by updating name.value. For example, let's say that I want to change my name from Sunil to John. I'd do this by writing name.value = "John". I’m not sure how I feel about being called John, but hey ho, things happen!
Effectively React and Vue are doing the same thing here, which is creating data that can be updated. Vue essentially combines its own version of name and setName by default whenever a piece of data wrappeed inside of a ref() function gets updated. React requires that you call setName() with the value inside in order to update state, Vue makes an assumption that you’d want to do this if you were ever trying to update values inside the data object. So Why does React even bother with separating the value from the function, and why is useState() even needed? Essentially, React wants to be able to re-run certain life cycle hooks whenever state changes. In our example, if setName() is called, React will know that some state has changed and can, therefore, run those lifecycle hooks. If you directly mutated state, React would have to do more work to keep track of changes and what lifecycle hooks to run etc.
Now that we have mutations out of the way, let’s get into the nitty, gritty by looking at how we would go about adding new items to both of our To Do Apps.
[/SHOWTOGROUPS]