Reputation: 430
So I am fetching an array of objects to fill my datatable, there is no issue with the fetching as i get the data I need in the format I need. I retrieve it from my redux store like so:
const contractorList = useSelector(state => state.contractorList)
const { loading, error, contractors } = contractorList
In my useEffect
I check if the user is logged in, if so, I dispatch my action to get my data, map through it and push each object to my data
array which is a state like so:
const [data, setData] = useState([])
Finally I have set the source of my DataTable to be my state array here:
<DataTable
noHeader
pagination
selectableRowsNoSelectAll
columns={columns}
className='react-dataTable'
paginationPerPage={25}
sortIcon={<ChevronDown size={10} />}
paginationDefaultPage={currentPage + 1}
data={data}
/>
The Problem is as follows, if I visit the page initially, the data loads in the table fine, or if I navigate to this page from anywhere else in the app it seems to work grand. However if I manually refresh the page (so clicking the refresh button on my browser) I am met with "No Data to display" on my table. Almost as if the useEffect doesnt fire when I refresh. Anyone know why? I'm lost and I can't see it being an issue with my redux or useEffect as it works when navigating in the app.
Here is the useEffect:
useEffect(() => {
if(userInfo ) {
if(userInfo) {
dispatch(listContractors())
if(contractors) {
contractors.map(c => {
setData(data => [...data, {
action: <Link className='text-dark text-center' to={`/contractor/${c._id}`}><MoreHorizontal /></Link>,
psa_licence_no: c.psa_licence_no,
company: c.company,
trading_as: c.trading_as,
address_1: c.address_1,
address_2: c.address_2,
address_3: c.address_3,
county: c.county,
eircode: c.eircode,
contact_f_name: c.contact_f_name,
contact_s_name: c.contact_s_name,
office_tel_no: c.office_tel_no,
mobile_tel_no: c.mobile_tel_no,
sentinel_id: c.sentinel_id,
email: c.email,
intruder: c.intruder,
cctv: c.cctv,
guard_static: c.guard_static,
arc_intruder: c.arc_intruder,
arc_cctv: c.arc_cctv,
issue_date: c.issue_date,
expiry_date: c.expiry_date,
psa_date_added: c.psa_date_added,
psa_date_updated: c.psa_date_updated,
psa_date_removed: c.psa_date_removed
}])
})
}
}
} else {
history.push('/login')
}
}, [dispatch, userInfo, history, successCreate])
If I add contractors
to the list of dependencies, then it created an infinite loop of doing the listContractors
action
Upvotes: 1
Views: 1936
Reputation: 196002
I would break your useEffect to two since they handle different parts of your code, one to dispatch a fetch and the other to massage the data when received.
// this will dispatch the listContractors action when the userInfo changes
useEffect(() => {
if (userInfo) {
dispatch(listContractors())
} else {
history.push('/login')
}
}, [userInfo, history])
// this will update the data when contractors is changed
useEffect(() => {
if (contractors) {
const transformedContractors = contractors.map(contractor => ({
...contractor, // used this to avoid the one-by-one hand written copy.
action: <Link className='text-dark text-center' to={`/contractor/${c._id}`}><MoreHorizontal /></Link>
}));
setData(transformedContractors);
}
}, [contractors]);
Upvotes: 1