Laptop screen showing employee search and directory with filters for status, department, job title, location, skills, and date joined.
Laptop screen showing employee search and directory with filters for status, department, job title, location, skills, and date joined.
A laptop displaying an employee search and directory tool with filtering options in an office.

Technical Blog Article — App 29: Employee Search with React, TypeScript, Vite, and Fluent UI

App 29 — Employee Search is one of the most important applications in Block 2 — Interactivity and State because it introduces one of the core mental models of modern React:

UI derived from state

This application may look simple visually, but architecturally it teaches:

  • controlled inputs
  • state-driven rendering
  • derived data
  • filtering collections
  • reusable component composition
  • declarative rendering
  • proper React state organization
  • avoiding unnecessary useEffect

The roadmap defines App 29 as:

“Employee Search / Pesquisa de Funcionários — Inputs + Filters”

and directly connects it to React’s concepts of:

  • state sharing
  • derived rendering
  • component composition
  • controlled forms

The application simulates a small enterprise employee directory similar to interfaces found in:

  • Microsoft 365 admin centers
  • SharePoint intranets
  • HR systems
  • CRM systems
  • corporate dashboards
  • internal employee portals

This app is extremely important because it represents the transition from:

  • static UI
    to:
  • dynamic UI driven by user interaction

The Main React Concept Introduced

Before App 29, most apps were primarily static visual composition.

Now React becomes interactive.

The most important architectural idea introduced here is:

The interface changes automatically when state changes.

This is the foundation of React.

The user types text into the search box.

That text updates React state.

React recalculates filtered employees.

React re-renders the list automatically.

No manual DOM manipulation happens.


Why This App Matters

This application introduces several professional frontend concepts simultaneously:

ConceptWhy It Matters
Controlled InputCore React form pattern
State ManagementUI driven by data
Derived DataAvoid duplicated state
Filtering CollectionsCommon enterprise behavior
Component CompositionScalable architecture
Fluent UI FormsEnterprise UX patterns
TypeScript ModelsStrong typing
Declarative RenderingModern React mental model

This architecture appears everywhere in enterprise systems.

For example:

  • employee search
  • product search
  • SharePoint document filters
  • CRM customer lookup
  • dashboard filtering
  • report search
  • admin panels

App 29 is the first true “search-driven UI” in the roadmap.


Creating the Project

The project begins with Vite.

PowerShell commands

cd C:\ReactApps
mkdir bloco02
cd bloco02
npm create vite@latest app29-employee-search -- --template react-ts
cd app29-employee-search
npm install

Installing Fluent UI

npm install @fluentui/react-components @fluentui/react-icons

Fluent UI is the official Microsoft React design system.

It provides:

  • accessibility
  • typography
  • spacing
  • enterprise controls
  • keyboard support
  • consistent design language

Instead of manually building controls from scratch, we use professional reusable components.


Creating the Folder Structure

mkdir src\components
mkdir src\data
mkdir src\models
mkdir src\styles

This architecture matters enormously.

Even small React apps should begin organized.


Why Folder Structure Matters

components/

Contains reusable UI pieces.

Examples:

  • cards
  • forms
  • headers
  • search bars
  • lists

models/

Contains TypeScript interfaces and types.

This creates:

  • strong typing
  • predictable architecture
  • safer refactoring

data/

Contains mock or static data.

Later this evolves into:

  • APIs
  • services
  • REST calls
  • repositories

styles/

Prepared for:

  • layout styles
  • responsive behavior
  • themes
  • reusable CSS

Understanding the Employee Model

File:

src/models/Employee.ts

Code:

export interface Employee {
id: number;
name: string;
role: string;
department: string;
location: string;
status: "Active" | "On Leave" | "Remote";
}

This file introduces a critical enterprise concept:

TypeScript models

Why Models Matter

Enterprise applications deal with structured data.

An employee always has:

  • name
  • role
  • department
  • location
  • status

The interface defines that structure.

Without models:

  • bugs increase
  • code becomes unclear
  • refactoring becomes dangerous

TypeScript ensures consistency.


Understanding Literal Types

This part is especially important:

status: "Active" | "On Leave" | "Remote";

This is called a union literal type.

It means:

status can ONLY be:
- Active
- On Leave
- Remote

If you accidentally write:

status: "Vacation"

TypeScript will show an error.

This prevents invalid states.


Understanding the Data Layer

File:

src/data/employees.ts

This file contains static employee data.

Example:

export const employees: Employee[] = [

The array type:

Employee[]

means:

This array contains Employee objects.

This gives:

  • autocomplete
  • validation
  • safer filtering
  • predictable rendering

Why Static Data Is Important First

Notice something important:

There is:

  • no API
  • no fetch
  • no database

This is intentional.

React Learn strongly recommends understanding rendering and state before introducing effects and APIs.

The application focuses only on:

  • rendering
  • filtering
  • component composition

This avoids unnecessary complexity.


Understanding Controlled Inputs

One of the most important React concepts appears in:

const [searchText, setSearchText] = useState("");

This creates component state.


Understanding useState

React state is component memory.

The syntax:

const [searchText, setSearchText] = useState("");

contains three parts.


1. searchText

The current state value.

Initially:

""

an empty string.


2. setSearchText

The state update function.

This tells React:

Update the value and re-render the UI.

3. useState("")

Creates state with initial value.


The Most Important React Flow in This App

This entire application works through this cycle:

User types text
onChange fires
setSearchText updates state
React re-renders App
filteredEmployees recalculates
EmployeeList receives new data
UI updates automatically

This is the React mental model.


Understanding Controlled Inputs

The search box uses:

<Input
value={searchText}
onChange={(_, data) => onSearchTextChange(data.value)}
/>

This is called a controlled component.

The input value is controlled by React state.


Why Controlled Inputs Matter

Without controlled inputs:

  • React does not fully own the form state
  • validation becomes harder
  • synchronization becomes harder

Controlled inputs make the UI predictable.

React becomes the source of truth.


Understanding the Search Component

File:

EmployeeSearchBox.tsx

Props:

interface EmployeeSearchBoxProps {
searchText: string;
onSearchTextChange: (value: string) => void;
}

This component does not own state.

That is extremely important.

Instead:

  • App owns state
  • SearchBox receives value + callback

This follows React’s architecture principles.


Why State Lives in App.tsx

React docs explain:

State should live in the closest common parent.

App.tsx owns:

  • search input value
  • filtered employees

because multiple components depend on it.


Understanding Derived Data

This is one of the most important concepts in the app:

const filteredEmployees = employees.filter(...)

This is derived state.

React Learn strongly recommends:

Do not duplicate state unnecessarily.

Notice:

We do NOT store:

  • filteredEmployees in state

Instead:

  • we calculate it from existing state

This is correct React architecture.


Why Derived State Matters

Bad approach:

const [filteredEmployees, setFilteredEmployees] = useState(...)

This duplicates data.

Duplicated state causes:

  • synchronization bugs
  • inconsistent UI
  • harder debugging

Correct approach:

const filteredEmployees = employees.filter(...)

The filtered data is derived automatically.


Understanding the Filter Logic

The code:

const searchableText = `
${employee.name}
${employee.role}
${employee.department}
${employee.location}
${employee.status}
`.toLowerCase();

creates one searchable string.

Then:

return searchableText.includes(normalizedSearchText);

checks if the search text exists inside it.


Why .toLowerCase() Matters

This makes search case-insensitive.

Without it:

Anna
anna
ANNA

would behave differently.

This improves UX significantly.


Understanding trim()

searchText.toLowerCase().trim()

trim() removes extra spaces.

Example:

" anna "

becomes:

"anna"

This avoids accidental whitespace problems.


Understanding Declarative Rendering

React rendering here uses:

employees.map(...)

This is declarative UI generation.

You are not manually creating DOM elements.

Instead you describe:

For each employee, render an EmployeeCard.

React handles the DOM updates.


Understanding React Keys

key={employee.id}

Keys are critical in React lists.

React uses keys to:

  • track elements
  • optimize rendering
  • correctly update changed items

Without keys:

  • React warnings appear
  • rendering becomes less efficient

Understanding the Employee Card

File:

EmployeeCard.tsx

This component is responsible for rendering one employee.

This separation is extremely important.


Why Small Components Matter

Instead of one giant file, React applications scale through composition.

The architecture becomes:

App
EmployeeSearchBox
EmployeeList
EmployeeCard

Each component has one responsibility.


Understanding Fluent UI Cards

The card:

<Card>

acts as a visual enterprise container.

Cards are heavily used in:

  • dashboards
  • admin systems
  • SharePoint layouts
  • Microsoft portals

Fluent UI cards already include:

  • spacing
  • borders
  • shadows
  • accessibility behavior

Understanding Badge Appearance

This logic:

function getBadgeAppearance(status: Employee["status"])

maps employee status into UI appearance.

Example:

StatusAppearance
Activefilled
Remotetint
On Leaveoutline

This separates:

  • business logic
    from:
  • rendering

That is good architecture.


Understanding Component Purity

Notice something important.

EmployeeCard:

  • receives props
  • returns JSX

It does not:

  • modify external variables
  • manipulate the DOM directly
  • fetch data
  • mutate state

This makes it a pure component.

React Learn strongly emphasizes pure rendering.


Why There Is No useEffect

This app intentionally avoids useEffect.

That is correct.

The app only:

  • reacts to user input
  • derives filtered data

No external synchronization exists.

According to React Learn:

“You Might Not Need an Effect.”

Filtering local data does NOT require effects.

This is one of the most important lessons in modern React.


Understanding the Main Layout

The app root uses:

<main>

This is semantic HTML.

It improves:

  • accessibility
  • screen readers
  • document structure

React still benefits from proper HTML semantics.


Understanding the Responsive Grid

The employee list uses:

gridTemplateColumns:
"repeat(auto-fit, minmax(260px, 1fr))"

This creates a responsive layout.

Meaning:

Create as many columns as fit.
Each column must be at least 260px.
Distribute extra space equally.

This allows responsive enterprise dashboards.


Understanding Fluent UI Inputs

The search box uses:

<Input />

This already includes:

  • keyboard accessibility
  • focus management
  • Microsoft design
  • proper spacing
  • enterprise interaction behavior

Without Fluent UI, this would require manual implementation.


Understanding the Search Icon

contentBefore={<Search24Regular />}

Fluent UI icons are:

  • SVG-based
  • scalable
  • theme-aware
  • optimized

This creates enterprise-style visual search UX.


Understanding the App Architecture

The full architecture becomes:

main.tsx
renders App.tsx
App.tsx
owns search state
EmployeeSearchBox.tsx
updates state
EmployeeList.tsx
renders collection
EmployeeCard.tsx
renders one employee
employees.ts
stores static data
Employee.ts
defines data shape

This is professional React structure.


Production Validation

Run development server

npm run dev

Validate production build

npm run build

This checks:

  • TypeScript compilation
  • JSX compilation
  • production bundling

This is equivalent to validating enterprise deployment readiness.


Preview production build

npm run preview

This serves the optimized production bundle locally.


Technical Summary

ConceptPurpose
useStateComponent memory
Controlled InputReact-controlled form
Derived DataAvoid duplicated state
filter()Collection filtering
map()Declarative rendering
TypeScript InterfaceStrong typing
Fluent UIEnterprise components
Component CompositionScalable architecture
Pure ComponentsPredictable rendering
Responsive GridAdaptive layout

Official Documentation

React

Fluent UI

Vite

TypeScript


Current Project Progress

BlockAppNameStatus
Block 101Hello React FluentCompleted
Block 102Profile CardCompleted
Block 103Product ListCompleted
Block 104Microsoft Style User CardCompleted
Block 105Static DashboardCompleted
Block 106Corporate Sidebar MenuCompleted
Block 107Visual Task ListCompleted
Block 221Modern CounterCompleted
Block 222Toggle ThemeCompleted
Block 223React CalculatorCompleted
Block 224Login FormCompleted
Block 225User RegistrationCompleted
Block 226Complete ToDo ListCompleted
Block 227Shopping ListCompleted
Block 228Product FilterCompleted
Block 229Employee SearchCurrent
Block 230Shopping CartNext

Edvaldo Guimrães Filho Avatar

Published by