Complete worked example
typescript
import {useState} from "react";
type Role={id:string;title:string;country:"US"|"UA"};
export function RoleExplorer({roles}:{roles:readonly Role[]}){
const [query,setQuery]=useState("");
const visible=roles.filter(role=>role.title.toLowerCase().includes(query.trim().toLowerCase()));
return <section><label>Search roles<input value={query} onChange={event=>setQuery(event.currentTarget.value)}/></label>
{visible.length?<ul>{visible.map(role=><li key={role.id}>{role.title}</li>)}</ul>:<p>No matching roles</p>}</section>;
}- Reasoning
- The component receives trusted data and derives filtered results rather than synchronizing duplicate state through an effect.