I have a component that looks like this
import { useState, useEffect, useMemo } from 'react'
import Input from '~/components/Input'
import Fuse from 'fuse.js'
interface Props {
data: any[]
keys: string[]
onUpdate: (data: any[]) => void
placeholder: string
}
const FilterInput = ({ data, keys, onUpdate, placeholder }: Props) => {
const [search, setSearch] = useState('')
const handleSearch = (e) => setSearch(e.target.value)
// Memorize the fuse instance to avoid recreating it on every render
const fuse = useMemo(() => {
return new Fuse(data, {
includeScore: true,
keys,
threshold: 0.3,
distance: 100,
})
}, [data, keys]) //THIS IS THE RELEVANT PART
useEffect(() => {
const results =
search === '' ? data : fuse.search(search).map((result) => result.item)
onUpdate(results) // Invoke onUpdate with the filtered or original list
}, [search, fuse, onUpdate, data]) // Effect dependencies
return (
<div className={'mb-10'}>
<Input value={search} onChange={handleSearch} placeholder={placeholder} />
</div>
)
}
export default FilterInput
I am using it like this
const ProjectFeatureListing = ({ projects }: Props) => {
const [filteredProjects, setFilteredProjects] = useState(projects) // State to hold the filtered list
console.log(projects)
return (
<div className={'max-w-7xl py-10 mx-auto px-10'}>
<FilterInput
data={projects}
keys={['title', 'description']}
onUpdate={setFilteredProjects}
placeholder={'Find our creators'}
/>
...
I can't figure out why sending this static array would trigger a re-render since it's not changing, to be clear when I do this
const fuse = useMemo(() => {
return new Fuse(data, {
includeScore: true,
keys,
threshold: 0.3,
distance: 100,
})
}, [data]) //THIS IS THE RELEVANT PART
It does NOT infinitely re-render
===
UPDATE:
I added this code
// Ref to store the previous keys
const prevKeysRef = useRef(keys)
// Check if keys have the same reference
const keysHaveSameReference = keys === prevKeysRef.current
console.log('Keys have the same reference:', keysHaveSameReference)
// Update prevKeysRef with the current keys
useEffect(() => {
prevKeysRef.current = keys
}, [keys])
And I can confirm that the ref to keys is changing