I am creating a small list using React Hook Form with useFieldArray. I want to filter the list when the user types anything in the search field. However, the filtering is not working.
Below is my code:
import React from 'react';
import { useForm, useFieldArray, Controller, useWatch } from 'react-hook-form';
import ReactDOM from 'react-dom';
let renderCount = 0;
export function App() {
const { register, control, handleSubmit, reset, watch } = useForm({
defaultValues: {
test: [
{ firstName: 'Bill 1', lastName: 'Luo' },
{ firstName: 'hello2', lastName: 'Luo' },
{ firstName: 'test 3', lastName: 'Luo' },
{ firstName: 'test 4', lastName: 'Luo' },
],
},
});
const { fields, append, prepend, remove, swap, move, insert, replace } =
useFieldArray({
control,
name: 'test',
});
const onSubmit = data => console.log('data', data);
const [searchQuery, setSearchQuery] = React.useState('');
const handleSearchChange = event => {
setSearchQuery(event.target.value);
};
const filteredRows = fields.filter(row =>
row.firstName.toLowerCase().includes(searchQuery.toLowerCase())
);
console.log(JSON.stringify(filteredRows));
return (
<>
<input onChange={handleSearchChange} value={searchQuery} />
<form onSubmit={handleSubmit(onSubmit)}>
<ul>
{filteredRows.map((item, index) => {
return (
<li key={item.id}>
<input
{...register(`test.${index}.firstName`, { required: true })}
/>
<Controller
render={({ field }) => <input {...field} />}
name={`test.${index}.lastName`}
control={control}
/>
</li>
);
})}
</ul>
</form>
</>
);
}
// Log to console
console.log('Hello console');
when I search "test" it is showing first two rows instead of last two rows. why?
You are using the index of the filtered list when referring to the first name and last name. You need to refer to the index of the original list
{filteredRows.map((item, index) => {
return (
<li key={item.id}>
<input
{...register(`test.${fields.findIndex((i) => i === item)}.firstName`, { required: true })}
/>
<Controller
render={({ field }) => <input {...field} />}
name={`test.${fields.findIndex((i) => i === item)}.lastName`}
control={control}
/>
</li>
);
})}