import React, { useEffect, useState } from "react";
function Table(){
const [getData,setData]=useState([]);
const [search, setSearch] =useState('')
//Getting user data
useEffect(()=>{
fetch("http://localhost:5000/students/getStudents")
.then(resp=>resp.json())
.then(data=> setData(data))
},[]);
const changeHandler = (event)=>{
setSearch(event.target.value)
}
const searchOp = getData.filter((data)=>{
return data.includes(search)
})
return(
<div className='table_content'>
<input type='text' value={search} onChange={changeHandler} placeholder='Search'/>
<table>
<tr>
<th>Registration Number</th>
<th>Name</th>
<th>Grade</th>
<th>Subjects</th>
</tr>
{searchOp.map(data=>
<tr key={data._id}>
<td>{data.registrationNumber}</td>
<td>{data.name}</td>
<td>{data.grade}</td>
<td>{data.subjects}</td>
</tr>
)}
</table>
</div>
)
}
export default Table;
Current error:
[Error] TypeError: data.includes is not a function. (In 'data.includes(search)', 'data.includes' is undefined) commitRootImpl (bundle.js:36197) commitRoot (bundle.js:35989) finishConcurrentRender (bundle.js:35198) performConcurrentWorkOnRoot (bundle.js:35116) performConcurrentWorkOnRoot workLoop (bundle.js:44067) flushWork (bundle.js:44041) performWorkUntilDeadline (bundle.js:44325)
CodePudding user response:
The problem is that your API call is asynchronous, while react will render the component right away, and then rerender it when the data is received. This means that upon first render, return data.includes(search)
will receive an empty array as defined in const [getData,setData]=useState([]);
which in turns means that data
will be undefined and includes()
is indeed not a function of undefined
.
One few possible solutions could be:
- Put a null-check on your method:
const searchOp = getData.filter((data)=>{
return data?.includes(search)
})
- Conditionally render
searchOp
{getData.length > 0 && searchOp.map(data=>
<tr key={data._id}>
<td>{data.registrationNumber}</td>
<td>{data.name}</td>
<td>{data.grade}</td>
<td>{data.subjects}</td>
</tr>
)}
CodePudding user response:
So I change my searchOp function and is currently working. But feel like might lead to problems later. Please advise if this is a good solution or not
const searchOp = getData.filter((data)=>{
if(Object.values(data).includes(search)){
return search;
}
else if(search===""){
return getData;
}
})