I have a filter function which is filtering data with state data, dataCopy and searchValue. Issue is if i don't include the data state than react gives warning and if i do include it it cause infinite loop cause the data array is changing within the useEffect. How can i make so that i don't get that warning.
Filter function
import React, { useEffect, useState } from 'react'
import Header from '../Components/Header/Header'
import Home from '../Components/Home/Home'
import "./Layout.css"
import Spinner from '../Components/Spinner/Spinner'
function Layout() {
// state for data, copy of data and spinner
const [data, setData] = useState([])
const [dataCopy, setDataCopy] = useState([])
// state for search input in Header.js (define in parent )
const [searchValue, setSearchValue] = useState("")
// changing search value
const changeSearchValue = (value) => {
setSearchValue(value)
}
// useEffect for search functionality
useEffect(() => {
const handleSearch = () => {
if (searchValue !== "") {
const searchFilter = data.filter(item =>
!isNaN(searchValue) ? item.expected_annually_bill_amount.toString().includes(searchValue) :
item.dmo_content.Ausgrid.toString().toLowerCase().includes(searchValue.toLowerCase()))
setData(searchFilter)
} else {
setData(dataCopy)
}
}
handleSearch()
}, [searchValue, dataCopy])
// useEffect for getting data from api
useEffect(() => {
// making post request to get the token
axios.post(`${process.env.REACT_APP_BASE_URL}`, { data: "" },
{
headers:
{
'Api-key': `${process.env.REACT_APP_API_KEY}`,
},
})
// after getting to token returning it for callback
.then((response) => {
return response.data.data.token
})
// using the token to call another api for the needed data
.then((tokenIs) => {
axios.post(`${process.env.REACT_APP_DATA_URL}`,
{ "session_id": `${process.env.REACT_APP_SESSION_ID}` },
{
headers:
{
'Api-key': `${process.env.REACT_APP_API_KEY}`,
'Auth-token': tokenIs,
},
})
.then((response) => {
setData(response.data.data.electricity)
setDataCopy(response.data.data.electricity)
setSpinner(false)
})
})
// catiching any error if happens
.catch((err) => {
setSpinner(false)
alert(err)
})
}, [])
return (<>
<div className='layout'>
<Header
changeSearchValue={changeSearchValue}
searchValue={searchValue}
/>
<Home data={data} />
</div>
)
}
export default Layout
CodePudding user response:
You can add the following comment above the dependency array for suppressing the warning
// eslint-disable-next-line react-hooks/exhaustive-deps
CodePudding user response:
Here you can eliminate data
dependency by:
useEffect(() => {
const handleSearch = () => {
if (searchValue !== "") {
setData(data => data.filter(item =>
!isNaN(searchValue) ? item.expected_annually_bill_amount.toString().includes(searchValue) :
item.dmo_content.Ausgrid.toString().toLowerCase().includes(searchValue.toLowerCase())))
} else {
setData(dataCopy)
}
}
handleSearch()
}, [searchValue, dataCopy])