Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React JS Filters being overwritten by setState data in useEffect

I have a table where I’m setting data inside a useEffect from an api. My filter logic iterates through the "rows" variable which is being set inside this useEffect. However, every-time the user searches via an input which has an onChange event the useEffect setRows I believe is setting the data over and over again.

What would be a better way to set the data so it doesn’t conflict with my filtering logic?

//State

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const [documents, setDocuments] = useState<IDocument[]>([]);
const [rows, setRows] = useState<Data[]>([]);

//useEffect to setData

useEffect(() => {
//setDocuments from claimStore when component mounts
    setDocuments(claimsStore.getIncomingDocuments());

    //setRows from documents when component mounts
    setRows(
        documents.map((document) =>
        createData(
            document.documentAuthor ?? '',
            document.documentMetadataId.toLocaleString(),
            document.documentMetadataId.toLocaleString(),
            document.documentName ?? '',
            document.documentSource ?? '',
            document.documentType,
            document.featureId ?? '',
            document.mimeType,
            document.uploadDateTime,
        ),
        ),
    ); 
}, [claimsStore, documents]);

//Filter logic that updates rows as user input values captured

const filterBySearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    const newFilters = { ...filters, [name]: value };
    //Update filters with user input
    setFilters(newFilters);

    //Filter documents based on user input
    const updatedList = rows.filter((document) => {
        return (
        document.documentAuthor.toLowerCase().includes(filters.documentAuthor.toLowerCase()) &&
        document.documentName.toLowerCase().includes(filters.documentName.toLowerCase()) &&
        document.documentSource.toLowerCase().includes(filters.documentSource.toLowerCase()) &&
        document.documentType.includes(filters.documentType === 'All' ? '' : filters.documentType) &&
        document.featureId.includes(filters.featureId) 
        );
    });

    //Trigger render with updated values
    setRows(updatedList);
};

Use of filterBySearch:

<TableCell align={'center'} className={classes.tableCell}>
    <input
    value={filters.featureId}
    onChange={(e) => filterBySearch(e)}
    name="featureId"
    className={classes.inputCell}
    />
</TableCell>   

>Solution :

This is one of the things useMemo is good for: Have an array of filtered rows, that you update as necessary when rows or filters changes:

const [documents, setDocuments] = useState<IDocument[]>([]);
const [rows, setRows] = useState<Data[]>([]);
// ...
const filteredRows = useMemo(
    () => rows.filter((document) => (
        document.documentAuthor.toLowerCase().includes(filters.documentAuthor.toLowerCase()) &&
        document.documentName.toLowerCase().includes(filters.documentName.toLowerCase()) &&
        document.documentSource.toLowerCase().includes(filters.documentSource.toLowerCase()) &&
        document.documentType.includes(filters.documentType === 'All' ? '' : filters.documentType) &&
        document.featureId.includes(filters.featureId) 
    )),
    [rows, filters]
);

Then filterBySearch is just:

const filterBySearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    const newFilters = { ...filters, [name]: value };
    //Update filters with user input
    setFilters(newFilters);
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading