Como alguien que ha navegado por las complejidades de React, Angular y Vue a lo largo de mi carrera, he llegado a apreciar las diferencias matizadas entre estos populares marcos de interfaz de usuario. En este artículo, describiré por qué optar por Angular o Vue podría ofrecer un enfoque más estructurado y escalable en comparación con React para su próximo proyecto de aplicación web.
Las plantillas en Angular y Vue ofrecen una clara separación de preocupaciones entre lógica y presentación, lo que fomenta un código más limpio y un mantenimiento más sencillo. A diferencia de JSX de React, donde la lógica de JavaScript se puede entrelazar con el marcado, las plantillas de Angular y Vue imponen una separación estricta. Ilustremos esto con ejemplos:
Reaccionar JSX:
return ( <div> {array.map(item => { if (condition) { return <p>{item}</p>; } else { return <span>{item}</span>; } })} </div> );
Plantilla angular:
<div *ngFor="let item of array"> <p *ngIf="condition; else other">{{ item }}</p> <ng-template #other><span>{{ item }}</span></ng-template> </div>
Plantilla de vista:
<div v-for="item in array"> <p v-if="condition">{{ item }}</p> <span v-else>{{ item }}</span> </div>
Angular y Vue proporcionan formas sencillas de vincular controles de formulario, lo que facilita la administración de datos de formulario con múltiples campos. Creemos un objeto de formulario con cuatro campos: entrada de texto, botón de opción, casilla de verificación y menú desplegable de selección.
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: '', }; }
Vista:
<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>
Reaccionar:
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> ); };
En React, sin usar bibliotecas como Formik o React Hook Form, administrar el estado del formulario requiere configurar variables de estado con useState
y escribir una función de controlador para actualizar el estado cada vez que cambian los campos del formulario. Esto puede agregar código repetitivo y aumentar la complejidad, especialmente para formularios con múltiples campos. Si bien las bibliotecas de formularios ofrecen capacidades avanzadas de manejo de formularios, integrarlas en un proyecto requiere configuración y aprendizaje adicionales.
En mi opinión, es posible que los desarrolladores no quieran perder tiempo eligiendo y aprendiendo documentación adicional para las bibliotecas de formularios, especialmente cuando el manejo de formularios es una tarea diaria típica para los desarrolladores frontend. Las capacidades integradas de manejo de formularios de Angular y Vue ofrecen un enfoque más simple e integrado, lo que permite a los desarrolladores concentrarse en crear sus aplicaciones sin la necesidad de dependencias adicionales.
ViewChild
de Angular, las referencias de Vue y useImperativeHandle
de React son mecanismos para interactuar con componentes secundarios. Si bien los tres proporcionan formas de lograr esto, Angular y Vue ofrecen enfoques más limpios e intuitivos en comparación con useImperativeHandle
de React, que es menos recomendado por la documentación de React. Aquí hay ejemplos:
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(); } }
Vista:
<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>
Reaccionar:
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> ); };
En React, si bien el paradigma del componente funcional no proporciona inherentemente "métodos" como los componentes de clase Angular o los componentes de Vue con la propiedad "métodos", se desea un enfoque más simple para acceder a métodos secundarios sin el gancho useImperativeHandle
. useImperativeHandle
puede ser menos claro y requiere envolver el componente secundario en la función forwardRef
. A diferencia de Angular y Vue, donde puede acceder a métodos secundarios sin alterar el componente secundario, React requiere esta configuración adicional para lograr una funcionalidad similar.
También quiero señalar sobre Vue. La API de composición es una tecnología relativamente nueva en Vue y el acceso a los componentes secundarios es un poco diferente a lo que describí anteriormente. Pero supongo que no todos los equipos han implementado todavía la API de composición en sus proyectos y utilizan el enfoque que describí.
He descrito tres razones por las que, en mi opinión, deberías elegir Angular o Vue en lugar de React.