Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
React is the most popular front end library for the last few years.
Vue is a front end framework that’s catching up in popularity with React in the last few years.
It’s hard to choose between the 2 frameworks since they both their pros and cons. When we choose one, we’ve to stick with it for a few years.
In this article, we’ll look at how we handle form input with React and Vue and which is better for developers.
Handling Form Input Values.
To handle form values with React, we have to add a onChange
handler in each input to set the value of the input in the state.
For example, if we have multiple inputs in our form, then we have to write the following code to do that:
import React, { useState } from "react";
export default function App() {
const [person, setPerson] = useState({});
const onSubmit = e => {
e.preventDefault();
alert(`${person.firstName} ${person.lastName}`);
};
return (
<div className="App">
<form onSubmit={onSubmit}>
<input
name="firstName"
placeholder="First Name"
onChange={e => setPerson({ ...person, firstName: e.target.value })}
/>
<br />
<input
name="lastName"
placeholder="Last Name"
onChange={e => setPerson({ ...person, lastName: e.target.value })}
/>
<br />
<input type="submit" value="Submit" />
</form>
</div>
);
}
In the code above, we have 2 inputs with onChange
handlers added to both to put the value that’s entered into the person
object.
Then we update the value by calling setPerson
with the object.
Once we did that, we can get the latest value of person
in our onSubmit
handler once we click Submit.
With all the onChange
handlers we have to add, it definitely gets tedious when our for has lots of inputs.
The Vue equivalent of the code above would be the following:
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<form @submit.prevent="onSubmit">
<input
name="firstName"
placeholder="First Name"
v-model="person.firstName"
/>
<br />
<input
name="firstName"
placeholder="Last Name"
v-model="person.lastName"
/>
<br />
<input type="submit" value="Submit" />
</form>
</div>
<script src="index.js"></script>
</body>
</html>
index.js
:
const app = new Vue({
el: "#app",
data: {
person: {
firstName: "",
lastName: ""
}
},
methods: {
onSubmit() {
alert(`${this.person.firstName} ${this.person.lastName}`);
}
}
});
The Vue has the same form, but we can bind the input value to our Vue’s data
value by using the v-model
directive.
This is shorter than adding an onChange
handler to every input that we have in our form.
Also, to call preventDefault
, we can just write: .prevent
instead of calling it explicitly, which is a nice shortcut that’s not available in React.
Handling form input is definitely cleaner with Vue than with React.
Handling Checkboxes
We can bind our checkbox choices to the Vue component’s model by setting the v-model
directive to the same array.
For example, we can write the following code to do that:
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="checkbox" value="Jane" v-model="checkedNames" />
<label>Jack</label>
<input type="checkbox" value="Mary" v-model="checkedNames" />
<label>John</label>
<input type="checkbox" value="Mike" v-model="checkedNames" />
<label>Mike</label>
<br />
<span>Checked names: {{ checkedNames }}</span>
</div>
<script src="index.js"></script>
</body>
</html>
index.js
:
const app = new Vue({
el: "#app",
data: {
checkedNames: []
}
});
As we can see, we just have to declare the checkNames
model in the data
object and then we just set the value of v-model
to checkedNames
to get all the values that are checked.
With React, we have to update the value of each checkbox with an onChange
handler that combines the old values with the new values, then we display the checked values by filtering out the ones that aren’t checked.
We write the following to do that:
import React, { useState } from "react";
export default function App() {
const [checkedNames, setCheckedNames] = useState({});
const handleCheck = e =>
setCheckedNames({
...checkedNames,
[e.target.value]: e.target.checked
});
return (
<div className="App">
<input type="checkbox" value="Jane" onChange={handleCheck} />
<label>Jack</label>
<input type="checkbox" value="Mary" onChange={handleCheck} />
<label>John</label>
<input type="checkbox" value="Mike" onChange={handleCheck} />
<label>Mike</label>
<br />
<span>
Checked names:{" "}
{Object.keys(checkedNames)
.filter(name => checkedNames[name])
.join(", ")}
</span>
</div>
);
}
In the code above, we created a handleCheck
function to combine the existing checkbox entries, which has the value of the checkbox as the key and the checked value of each checkbox as the value.
Then to display the values that are checked, we have to filter out the ones that aren’t checked and then convert the resulting array to a string.
This is definitely much more work than just binding the values to v-model
and then displaying an array as-is on the template in the Vue version.
Verdict
Vue’s v-model
really takes the hard work out of form handling. Text input is easy to handle, and checkboxes are even more so.
To handle form values with React, we need onChange
handlers for every input.
As we can see, if handling the value of a simple set of checkboxes is so complex with React, then if we have more inputs in a form, then it’s going to get even more complex.
We have to add a few lines of code just to display the checked values in the React example, which isn’t ideal.