1. React Directives (Conditional Rendering)
// EmployeeList.tsx - Conditional rendering with logical AND (&&) operator
{hasPermission('ADMIN') && (
<Button variant="secondary" className="ms-2">
Export Data
</Button>
)}
// AuthContext.tsx - Conditional navigation based on role
if (user.role.roleName === 'ADMIN') {
navigate('/admin');
} else {
navigate('/dashboard');
}
// ProtectedRoute.tsx - Conditional rendering with ternary operator
return !authState.isAuthenticated ?
<Navigate to={redirectTo} replace /> :
<Outlet />;
2. Data Binding
// Login.tsx - Two-way data binding with form inputs
<Form.Control
type="text"
name="userName"
value={credentials.userName} // Data binding (state to view)
onChange={handleChange} // Data binding (view to state)
required
/>
// EmployeeForm.tsx - One-way binding with select dropdown
<Form.Select
name="deptId"
value={employee.deptId} // One-way binding
onChange={onChange} // Event binding
>
{departments.map((dept) => (
<option key={dept.deptId} value={dept.deptId}>
{dept.deptName}
</option>
))}
</Form.Select>
3. Pipes (Data Transformation)
// EmployeeList.tsx - Formatting dates (similar to Angular pipes)
<td>{new Date(emp.dateOfJoining).toLocaleDateString()}</td>
// EmployeeView.tsx - Formatting currency
<p><strong>Salary:</strong> ${employee.salary.toFixed(2)}</p>
// Custom pipe-like function for role display
const formatRoleName = (role: string) => {
return role.charAt(0).toUpperCase() + role.slice(1).toLowerCase();
};
// Usage
<td>{formatRoleName(employee.role.roleName)}</td>
4. React Routing and Navigation
// App.tsx - Route configuration
<Routes>
<Route path="/login" element={<Login />} />
<Route element={<ProtectedRoute requiredRole="ADMIN" />}>
<Route path="/admin" element={<AdminDashboard />} />
</Route>
</Routes>
// Using useNavigate hook for programmatic navigation
const navigate = useNavigate();
const handleLogin = () => {
navigate('/dashboard', { replace: true });
};
// Link component for declarative navigation
<Link to="/employees/add" className="btn btn-success">
Add Employee
</Link>
// Navigation with state
navigate('/profile', { state: { from: 'dashboard' } });
// Accessing route parameters
const { empId } = useParams<{ empId: string }>();
// ProtectedRoute.tsx - Navigation guards
if (!authState.isAuthenticated) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
5. Key Implementation Notes:
React Directives:
Used
&&
operator for conditional rendering of componentsImplemented ternary operations for simple if-else rendering
Created
ProtectedRoute
component as a route guard directive
Data Binding:
Used React's controlled components for form inputs
Implemented two-way binding manually with
value
andonChange
Applied one-way binding for display components
Used context API for global state management
Pipes:
Created utility functions for data transformation
Used built-in JavaScript methods for formatting (toLocaleDateString, toFixed)
Implemented custom formatting functions for consistent display
Routing:
Configured nested routes with role-based protection
Used both programmatic and declarative navigation
Implemented route parameters for dynamic routing
Added navigation state for better UX
Created route guards for authentication and authorization
6. Additional Examples:
// Conditional class binding
<div className={`alert ${error ? 'alert-danger' : 'alert-success'}`}>
// Style binding
<button style={{ display: hasPermission ? 'block' : 'none' }}>
// List rendering
{employees.map(employee => (
<EmployeeCard key={employee.empId} employee={employee} />
))}
// Template interpolation (similar to pipes)
<h2>{`Welcome, ${user.userName}`}</h2>
// Query parameters
const [searchParams] = useSearchParams();
const filter = searchParams.get('filter');
These patterns follow React best practices while achieving similar functionality to Angular's directives, data binding, and pipes.
The main differences are:
React uses JavaScript expressions for directives rather than template syntax
Data binding is explicit rather than implicit
Pipes are replaced with JavaScript functions
Routing is component-based rather than configuration-based
No comments:
Post a Comment