...
/Refactoring the Filters Component
Refactoring the Filters Component
Learn how to refactor the filter component from a parent-child pattern to an internal state management pattern.
We'll cover the following...
Current Filters
component
Consider our current Filters
component:
Press + to interact
import * as React from "react";import { IFilter } from "../interfaces/IFilter";export interface IFiltersProps<T> {object: T;properties: Array<IFilter<T>>;onChangeFilter: (property: IFilter<T>, isChecked: boolean) => void;}export function Filters<T>(props: IFiltersProps<T>) {const { object, properties, onChangeFilter } = props;return (<div className="p-1 my-2"><label className="mt-3">Filters - try us too</label><br />// for each key in object, generate a truthy / falsey// checkbox pair{Object.keys(object).map((key: any) => {return (<>// truthy checkbox & label<inputtype="checkbox"id={`${key}-true`}value={key}onChange={(event) =>onChangeFilter({ property: key, isTruthySelected: true },event.target.checked)}// the 'some' function is used so that the checkbox can be checked// if just one of the properties matches with 'isTruthySelected'checked={properties.some((property) =>property.property === key && property.isTruthySelected)}className="m-1 ml-3"/>// string interpolation here to generate a unique key// and also the display contents of the label itself<label htmlFor={`${key}-true`}>`${key} is truthy`</label>// falsey checkbox & label<inputtype="checkbox"id={`${key}-false`}value={key}onChange={(event) =>onChangeFilter({ property: key, isTruthySelected: false },event.target.checked)}checked={properties.some((property) =>property.property === key && !property.isTruthySelected)}className="m-1 ml-3"/><label htmlFor={`${key}-false`}>`${key} is falsy`</label><br /></>);})}</div>);}
Refactoring Steps
Let’s make the Filters
component responsible for its own state, like we did for the SearchInput
and Sorters
components. We’ll make the following changes:
- Remove the
object
prop,