React table doesnt render data on first render

221 Views Asked by At

I've been struggling with it for hours. When i first load my component, the table is empty. When i navigate between pages and come back to my component, the table show data properly, but at the first render of the component, it seems like it consider vehicleList to be empty, even if the props vehicleList changed in the console. I even tried to force re-render with a useEffect hooks, with vehicleList dependency, but it doesnt work. I've been reading a lot of posts about immutability and reference, but even when i try to destructuring [...vehicleList] before passing it to the table, it doesnt trigger the re render with the right props.


const VehiclesList = ({loading, setLoading, vehicleList, categoryList, setActiveMenuItem, setMountVehicleDetails, highlightRow}) => {

    const router = useRouter();
    const { status } = router.query;
    const [reloadPage, setReloadPage] = useState(false)

 
    useEffect(()=> {
        setReloadPage(!reloadPage)
    }, [vehicleList])

    return (
        
        <div className={classes.VehiclesList}>
            {loading ? null :
            <>
                <HeadCard
                    color="#DE5C5C"
                    background="#fff"
                    title={
                        <div className={classes.NavigationContainer}>
                            {<NavigationBtn
                                title={'Toutes catégories'}
                                width={'100px'}
                                height={'50px'}
                                category={'all'}
                            />}
                            {categoryList && categoryList.data ? categoryList.data.map((element, index) => {
                                return <NavigationBtn
                                            key={index}
                                            title={categoryList.data[index].data.name}
                                            category={categoryList.data[index].data.name}
                                            width={'50px'}
                                            height={'50px'}
                                        />
                            }
                            
                            ) : null}
            
                        </div>
                    }
                    icon='key'
                    loading={loading}
                />
                <Row>
                    <Col md="12">
                        <Card className="main-card mb-3">
                            <CardBody>
                                <ReactTable data={vehicleList? vehicleList : []}
                                    columns={[
                                {
                                    Header: "Informations",
                                    columns: [
                                        {
                                            Header: '',
                                            id: 'photo',
                                            accessor: (d) => <img src={d.pictures.length > 0 ? d.pictures[0].medium_url : 'https://static.teteamodeler.com/media/cache/thumb_400/coloriage-voitures.png'} alt = 'photo de la voiture' className={classes.Photo}/>,
                                        },
                                        {
                                            Header: "Marque",
                                            id: 'brand',
                                            maxWidth: 80,
                                            accessor: (d) => d.brand,
                                        },
                                        {
                                            Header: "Modèle",
                                            id: 'model',
                                            sortable: false,
                                            accessor: (d) => d.model,
                                        },
                                        {
                                            Header: "Catégorie",
                                            id: 'category',
                                            accessor: (d) => d.category.name,
                                        }
                                        ,
                                        {
                                            Header: "Registration",
                                            id: 'immatriculation',
                                            accessor: (d) => d.registration_number,
                                        },
                                        {
                                            Header: "Id",
                                            id: 'id',
                                            maxWidth: 80,
                                            accessor: (d) => d.id,
                                        },
                                    ],
                                }
                                
                                    ]}
                                defaultPageSize={vehicleList.length <=20 ? vehicleList.length : 20}
                                loading={loading}
                                loadingText="Chargement..."
                                nextText="Suivant"
                                previousText="Précédent"
                                noDataText="Aucune données correspondantes"
                                showPageSizeOptions={false}
                                className="-striped -highlight"
                                getTdProps={(state, rowInfo, column, instance) => {
                                    if(rowInfo !== undefined) {
                                      return {
                                      
                                        style: {
                                            background: rowInfo.row.id === highlightRow ? '#DE5C5C' : ''
                                          },
                                        onClick: (e) => {
                                          console.log('A Td Element was clicked!')
                                          console.log('it produced this event:', e)
                                          console.log('It was in this column:', column)
                                          console.log('It was in this row:', rowInfo)
                                          console.log('It was in this table instance:', instance)
                                          router.push(`/vehicles?status=vehicle_details&vehicle_id=${rowInfo.row.id}`)
                                          setActiveMenuItem(status)
                                          setMountVehicleDetails(true)
                                          setLoading(true)
                                        }
                                      }
                                      
                                    } else {
                                      return {}
                                    }
                                    
                                    
                                  }}
                                />
                            </CardBody>
                        </Card>
                    </Col>
                </Row>
            </>
            }
        </div>
        
    )
}

export default VehiclesList;

Parent component is :

const Vehicles = () => {

    //Data from route and localStorage
    const router = useRouter();
    const { status, category, vehicle_id } = router.query;
  
    const [activeMenuItem, setActiveMenuItem] = useState('categories_list');
    const [loading, setLoading] = useState(false);
    const [reloadPage, setReloadPage] = useState(false);
    const [highlightRow, setHighlightRow] = useState('');
    
    //Constant to start fetching
    const [mountVehicleList, setMountVehicleList] = useState(false);
    
    //Data from useSwr hooks
    const [vehicleList, setVehicleList] = useState([]);
    
    
  
    const session = new SessionService();
    const { dataFromFetch, error } = useSWR(mountVehicleList ? `${session.domain}/admin/vehicle/list` : null, url =>
      session.fetch(url, {
          method: 'POST',
          body: JSON.stringify({
            parametersToCheck: {limit: 0}
        })
      })
      ,
       {
          onSuccess: (dataFromFetch) => {
            setVehicleList(dataFromFetch)
            setMountVehicleList(false)
            setLoading(false)
          },
          onError: (err, key, config) => {
            console.log("error", err)
          }
      }
    )
    
      
    useEffect(()=> {
        setLoading(true)
        setMountVehicleList(true)
        // router.push('/vehicles?status=categories_list')
    }, [])
  
    useEffect(() => {
      setActiveMenuItem(category? `${status}/category/${category}` : status);
    }, [status, category]);
  
    useEffect(()=> {
      console.log('passed in useEffect reload page')
      setLoading(true)
      setMountDataForRateManagement(true)
    }, [reloadPage])
  
    const backArrowHandler = () => {
      router.back();
    }
    
    const menu = [
      {
        item: 'categories_list',
        label: 'Liste des catégories',
        route: '/vehicles?status=categories_list'
      },
      {
        item: category ? `${status}/category/${category}` : 'vehicles_list/category/all',
        label: 'Liste des voitures',
        route: category ? `/vehicles?status=vehicles_list&category=${category}` : '/vehicles?status=vehicles_list&category=all' 
      },
      {
        item: 'agencies_list',
        label: 'Liste des agences',
        route: '/vehicles?status=agencies_list'
      },
      {
        item: 'bookings_parameters',
        label: 'Paramètres des réservations',
        route: '/vehicles?status=bookings_parameters'
      },
      {
        item: 'rate_management',
        label: 'Gestion des tarifs',
        route: '/vehicles?status=rate_management'
      },
    ];
  
    const carMenu = [
      {
        item: 'vehicle_details',
        label:  'Détails véhicule',
        route: 'vehicles?status=vehicle_details',
      },
      {
        item: 'vehicle_calendar',
        label: 'Calendrier du véhicule',
        route: 'vehicles?status=vehicle_calendar'
      }
    ]
  
    const renderSwitch = (param) => {
  
      const vehicleListPerCategory = vehicleList && vehicleList.vehicleList ? vehicleList.vehicleList.data.filter(element => element.zc_category.name === category)  : [];
  
      switch(param) {
        case 'categories_list':
          return <div style={{width: '75vw'}}>
                    <CategoryList
                      setLoading={setLoading}
                      categoryList={categoryList}
                    />
                  </div>
        case 'bookings_parameters':
          return <BookingParameters />
        case `vehicles_list/category/${category}`:
          return <div style={{width: '75vw'}}>
                    <VehiclesList
                      categoryList={categoryList}
                      category={category}
                      loading={loading}
                      vehicleList={category === 'all' && vehicleList.vehicleList ? [...vehicleList.vehicleList.data] : [...vehicleListPerCategory]}
                      setActiveMenuItem={setActiveMenuItem}
                      setMountVehicleDetails={setMountVehicleDetails}
                      setLoading={setLoading}
                      highlightRow={highlightRow}
                    />
                  </div>
        case 'rate_management': 
          return <div style={{width: '75vw', overflowX: 'scroll'}}>
                    <RateManagement
                      loading={loading}
                      setLoading={setLoading}
                      degressionTimes={degressionTimes}
                      categoryItems={categoryItems}
                      reloadPage={reloadPage}
                      setReloadPage={setReloadPage}
                    />
                  </div>
        case 'vehicle_details':
          return <div style={{width: '75vw', overflowX: 'scroll'}}>
                    <VehicleDetails
                      categoryList={categoryList}
                      dataForSelects={dataForSelects}
                      vehicleDetails={vehicleDetails}
                      vehicleBrandsAndModels={vehicleBrandsAndModels}
                      setLoading={setLoading}
                      setMountVehicleList={setMountVehicleList}
                      setHighlightRow={setHighlightRow}
                    />
                </div>
          return
        default:
          return '';
      }
    }
  
    return (
      <Layout activeNav="vehicles">
          
            {renderSwitch(activeMenuItem)}
        
          
      </Layout>
    )
  }
  
  export default protect(Vehicles)

vehicleList is a prop from the parent component, fetching it from an api. So it's basically equal to [] at the first render, but it's finally equal to an array of items. Kinda new to nextJs and React, i hope i explained my problem well.

0

There are 0 best solutions below