As someone who has navigated the intricacies of React, Angular, and Vue throughout my career, I've come to appreciate the nuanced differences between these popular frontend frameworks. In this article, I'll outline why opting for Angular or Vue might offer a more structured and scalable approach compared to React for your next web application project.
1. Templates
Templates in Angular and Vue offer a clear separation of concerns between logic and presentation, which fosters cleaner code and easier maintenance. Unlike React's JSX, where JavaScript logic can be intertwined with markup, Angular and Vue templates enforce a strict separation. Let's illustrate this with examples:
React JSX:
return (
<div>
{array.map(item => {
if (condition) {
return <p>{item}</p>;
} else {
return <span>{item}</span>;
}
})}
</div>
);
Angular Template:
<div *ngFor="let item of array">
<p *ngIf="condition; else other">{{ item }}</p>
<ng-template #other><span>{{ item }}</span></ng-template>
</div>
Vue Template:
<div v-for="item in array">
<p v-if="condition">{{ item }}</p>
<span v-else>{{ item }}</span>
</div>
2. Binding Form Controls:
Angular and Vue provide straightforward ways to bind form controls, making it easy to manage form data with multiple fields. Let's create a form object with four fields: text input, radio button, checkbox, and select dropdown.
Angular:
@Component({
selector: 'app-form',
template: `
<form>
<input type="text" [(ngModel)]="formData.text" placeholder="Text Input">
<br>
<input type="radio" [(ngModel)]="formData.radio" value="option1"> Option 1
<input type="radio" [(ngModel)]="formData.radio" value="option2"> Option 2
<br>
<input type="checkbox" [(ngModel)]="formData.checkbox"> Checkbox
<br>
<select [(ngModel)]="formData.select">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
</form>
`,
})
export class FormComponent {
formData = {
text: '',
radio: '',
checkbox: false,
select: '',
};
}
Vue:
<template>
<form>
<input type="text" v-model="formData.text" placeholder="Text Input">
<br>
<input type="radio" v-model="formData.radio" value="option1"> Option 1
<input type="radio" v-model="formData.radio" value="option2"> Option 2
<br>
<input type="checkbox" v-model="formData.checkbox"> Checkbox
<br>
<select v-model="formData.select">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
</form>
</template>
<script>
export default {
data() {
return {
formData: {
text: '',
radio: '',
checkbox: false,
select: '',
},
};
},
};
</script>
React:
const FormComponent = () => {
const [formData, setFormData] = useState({
text: '',
radio: '',
checkbox: false,
select: '',
});
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData({
...formData,
[name]: type === 'checkbox' ? checked : value,
});
};
return (
<form>
<input type="text" name="text" value={formData.text} onChange={handleChange} placeholder="Text Input" />
<br />
<input type="radio" name="radio" value="option1" checked={formData.radio === 'option1'} onChange={handleChange} /> Option 1
<input type="radio" name="radio" value="option2" checked={formData.radio === 'option2'} onChange={handleChange} /> Option 2
<br />
<input type="checkbox" name="checkbox" checked={formData.checkbox} onChange={handleChange} /> Checkbox
<br />
<select name="select" value={formData.select} onChange={handleChange}>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
</form>
);
};
In React, without using libraries like Formik or React Hook Form, managing form state requires setting up state variables with useState
and writing a handler function to update the state whenever form fields change. This can add boilerplate code and increase complexity, especially for forms with multiple fields. While form libraries offer advanced form handling capabilities, integrating them into a project requires additional setup and learning.
In my opinion, developers may not want to spend time choosing and learning additional documentation for form libraries, especially when handling forms is a typical everyday task for frontend developers. Angular and Vue's built-in form handling capabilities offer a simpler and more integrated approach, allowing developers to focus on building their applications without the need for additional dependencies.
3. Accessing Child Components:
Angular's ViewChild
, Vue's refs, and React's useImperativeHandle
are mechanisms to interact with child components. While all three provide ways to achieve this, Angular and Vue offer cleaner and more intuitive approaches compared to React's useImperativeHandle
, which is less recommended by React's documentation. Here are examples:
Angular:
@Component({
selector: 'app-parent',
template: `
<app-child #child></app-child>
<button (click)="callChildMethod()">Call Child Method</button>
`,
})
export class ParentComponent {
@ViewChild('child') childComponent: ChildComponent;
callChildMethod() {
this.childComponent.someMethod();
}
}
Vue:
<template>
<div>
<child ref="child"></child>
<button @click="callChildMethod">Call Child Method</button>
</div>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
methods: {
callChildMethod() {
this.$refs.child.someMethod();
},
},
};
</script>
React:
const ChildComponent = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
someMethod() {
// Method logic
},
}));
return (
<p>I am a child</p>
);
});
const ParentComponent = () => {
const childRef = useRef(null);
// Access child component's method
const callChildMethod = () => {
childRef.current?.someMethod();
};
return (
<div>
<ChildComponent ref={childRef} />
<button onClick={callChildMethod}>Call Child Method</button>
</div>
);
};
In React, while the functional component paradigm doesn't inherently provide "methods" like Angular class components or Vue components with "methods" property, a simpler approach for accessing child methods without the useImperativeHandle
hook is desired. useImperativeHandle
can be less clear, and it requires wrapping the child component in the forwardRef
function. Unlike Angular and Vue, where you can access child methods without altering the child component itself, React requires this additional setup to achieve similar functionality.
I also want to note about Vue. The Composition API is a relatively new technology in Vue and access to child components is a little different than what I described above. But I assume that not all teams have yet implemented the Composition API in their projects and use the approach that I described.
I have described three reasons why, in my opinion, you should choose Angular or Vue instead of React.