onChange dosent get triggered on first change for filter function filterFn
, the changeDepartmentIdFilter
function dosent change the value of departmentIdFilter on first change example
if i write
apple
it consoles only
appl
here is the link to my whole project:
https://github.com/naveednaseer/delete_later/blob/master/frontend/src/components/Department.js
here is the code :
const Department = () => {
let [department, setDepartment] = useState([])
let [filteredDepartment, setFilteredDepartment] = useState([])
let [values, setValues] = useState({
modalTitle: '',
departmentName: '',
departmentId: 0,
departmentIdFilter: "",
departmentNameFilter: "",
departmentsWithoutFilter: [],
})
useEffect (() => {
getDepartments()
}, [])
let filterFn = () =>{
let departmentIdFilter = values.departmentIdFilter
let departmentNameFilter = values.departmentNameFilter
let filteredData = filteredDepartment.filter(
function(el){
return el.DepartmentId.toString().toLowerCase().includes(
departmentIdFilter.toString().trim().toLowerCase()
) &&
el.DepartmentName.toString().toLowerCase().includes(
departmentNameFilter.toString().trim().toLowerCase()
)
}
)
setDepartment(filteredData)
}
let changeDepartmentIdFilter = (e) => {
setValues({...values, 'departmentIdFilter': e.target.value})
filterFn()
}
let changeDepartmentNameFilter = (e) => {
console.log(e.target.value)
setValues({...values, 'departmentNameFilter': e.target.value})
filterFn()
}
let getDepartments = async () => {
let response = await fetch (variables.API_URL "department")
let data = await response.json()
setDepartment(data)
setFilteredDepartment(data)
}
return (
<div>
<button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => addClick()}>Add Department</button>
<table className="table table-striped">
<thead>
<tr>
<th>
<input className="form-control m-2" onChange={(e) => {changeDepartmentIdFilter(e)}} placeholder='Filter' />
DepartmentId
</th>
<th>
<input className="form-control m-2" onChange={(e) => {changeDepartmentNameFilter(e)}} placeholder='Filter' />
DepartmentName
</th>
<th>
Options
</th>
</tr>
</thead>
<tbody>
{department.map((dep) =>
<tr key={dep.DepartmentId}>
<td>{dep.DepartmentId}</td>
<td>{dep.DepartmentName}</td>
<td>
{/* >>>>>>EDIT BUTTON<<<<<< */}
<button type="button" className="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => editClick(dep)}>
</button>
{/* >>>>>>>DELETE BUTTON<<<<<<<<<<< */}
<button type="button" className="btn btn-light mr-1" onClick={() => deleteClick(dep.DepartmentId)}>
</button>
</td>
</tr>
)}
</tbody>
</table>
<div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog modal-lg modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{values.modalTitle}</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
</button>
</div>
<div className="modal-body">
<div className="input-group mb-3">
<span className="input-group-text">Department Name</span>
<input name = 'departmentName' type="text" className="form-control" value={values.departmentName} onChange={(e) => {changeDepartmentName(e)}} />
{/* <input type="text" className="form-control" value={departmentName} onChange={changeDepartmentName} /> */}
</div>
{values.departmentId == 0 ?
<button type="button" className="btn btn-primary float-start" onClick={() => createClick()}>Create</button> :
null
}
{values.departmentId != 0 ?
<button type="button" className="btn btn-primary float-start" onClick={() => updateClick()}>Edit</button> :
null
}
</div>
</div>
</div>
</div>
</div>
)
}
export default Department
CodePudding user response:
Naveed when you write apple and it console appl it just because you are setting state at onChange event so state is like asynchronous so it take some time that is why this behave like it. you can call your filter function in setTimeout like this;
let changeDepartmentIdFilter = (e) => {
setValues({...values, 'departmentIdFilter': e.target.value})
setTimeout(() => {
filterFn()
},0)
}
CodePudding user response:
You can achieve this while using useEffect
hook.
const [value, setValue] = useState('');
useEffect(() => {
console.log(value);
// Call filter function here
}, [value]);
const onChangeCallback= () => {
setValue('a');
}
So whenever your value changes filter function gets called.