BranOIE
BranOIE

Reputation: 430

React DataTable not repopulating after refresh

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

Answers (1)

Gabriele Petrioli
Gabriele Petrioli

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

Related Questions