React
React's theory of operation is based on fundamental principles that allow for the efficient and reactive construction of user interfaces. Below are the main concepts and mechanisms that support how React works.
React's Theory of Operation
1. Components
Components are the foundation of React's architecture. They allow you to split the UI into smaller, reusable pieces. There are two main types of components:
- Functional Components: These are JavaScript functions that return React elements. With the introduction of Hooks, they can manage state and side effects.
function MyComponent() {
return <div>Hello, world!</div>;
}
- Class Components: They use JavaScript's class syntax and can have lifecycle methods. Although still supported, their use is declining in favor of functional components.
class MyComponent extends React.Component {
render() {
return <div>Hello, world!</div>;
}
}
2. JSX (JavaScript XML)
JSX is a syntax extension that allows you to write HTML-like code inside JavaScript files. It makes creating React elements easier and the code more readable.
const element = <h1>My Title</h1>;
3. Props (Properties)
props are a mechanism for passing data from parent components to child components. They are immutable and help create components that can be reused in different contexts.
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Usage
<Greeting name="Maria" />
4. State
state is an object that stores data that can change over the lifecycle of a component. Changes to the state trigger re-renders of the component and its children.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
5. Component Lifecycle
Components have a lifecycle that spans several phases, such as mounting, updating, and unmounting. Class components have specific methods (like componentDidMount, componentDidUpdate, and componentWillUnmount) that allow code execution at different points in the lifecycle. In functional components, Hooks like useEffect play a similar role.
6. Rendering
Rendering in React is an efficient process. When a component's state or props change, React re-renders that component and its children. React uses a reconciliation algorithm to determine which parts of the component tree need to be updated, minimizing the number of direct DOM operations.
7. Virtual DOM
React uses a concept called the Virtual DOM, which is a lightweight representation of the real DOM. When there's a change in state or props, React updates the Virtual DOM. Then, it compares the Virtual DOM with the real DOM and calculates the difference (diffing). Only the parts that have changed are updated in the real DOM, which improves performance.
8. Hooks
Hooks are functions that let functional components access state and side-effect features. Examples of Hooks include useState, useEffect, useContext, among others.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`The count is: ${count}`);
}, [count]);
return <button onClick={() => setCount(count + 1)}>Increment</button>;
}
TDD - Vitest (Testing Library)
Testing with Testing Library makes it easier to write tests that are decoupled from the implementation. It simulates the real behavior of the component and allows you to use an interface that simulates clicks and reads content from the screen according to the component's expected behavior.
// UserManager.test.jsx
import { render, fireEvent, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import UserManager from './UserManager'; // Importing the component
describe('UserManager', () => {
it('should allow the user to add a manager and display it in the list', async () => {
render(<UserManager />);
// Step 1: Interact with the combobox
const input = screen.getByRole('combobox');
fireEvent.change(input, { target: { value: 'Manager A' } });
// Step 2: Check if the suggestions appear
const suggestion = await screen.findByText('Manager A');
expect(suggestion).toBeInTheDocument();
// Step 3: Select the manager
fireEvent.click(suggestion);
// Step 4: Check if the selected manager appears in the list
const selectedManager = screen.getByText('Manager A');
expect(selectedManager).toBeInTheDocument();
});
});