1

I have a functional component that requires receiving parameter (i.e. props.rosterMonth) from the parent component and then retrieving data from the database, finally pass the result to the children component.

My problem is, how to set the initial state for the children component?

import {useEffect,useReducer} from 'react';
import Roster from '../../../utils/Roster';
import RosterWebContext from '../../../utils/RosterWebContext';
import Testing from './Testing';
export default function VVTable(props){
    let dataReducer=(state,action)=>{
        switch (action.type){
            case 'updateRosterMonth':
                return action.value;
            default:return state;     
        }
    }
    const [contextValue, updateContext] = useReducer(dataReducer,{});
    useEffect(()=>{
        const getData = async () => {
            console.log("Undo:Get Data from DB");
            let roster = new Roster();
            let rosterList= await roster.get(props.rosterMonth.getFullYear(),props.rosterMonth.getMonth()+1);
            updateContext(
                {
                    type:'updateRosterMonth',
                    value:{rosterList}
                }
            );        
        }
        getData();
    },[props]);
    return(
        <table id="rosterTable">
            <RosterWebContext.Provider value={[contextValue, updateContext]}>
                <Testing/>
            </RosterWebContext.Provider>
        </table>    
    )
}   

This is the Testing component.

import {useContext,useEffect} from 'react';
import RosterWebContext from '../../../utils/RosterWebContext';
export default function Testing(props){
    let [contextValue,updateContext]=useContext(RosterWebContext);
    useEffect(()=>{
        console.log(contextValue.rosterList);
    },[contextValue])
    return(
        <tbody>
        </tbody>
    )
}

Currently, I set the initial state to an empty object, so the child component 'Testing' may receive an empty object, to prevent the undefined object error, I need to write some code to check the incoming context value. If I can set the database value to the initial state, I can remove those checking code.

Linda Paiste
  • 38,446
  • 6
  • 64
  • 102
The KNVB
  • 3,588
  • 3
  • 29
  • 54

1 Answers1

1

The data from the database will always be delayed because it has to be retrieved via that API call from the server, (unless you are doing server side rendering). So you have to deal with the fact that at the beginning you don't have a rosterlist..

What I would do in this case is check if contextvalue.rosterList is defined and if it's not display a nice loading spinner to the user, something like this:

import {useContext,useEffect} from 'react';
import RosterWebContext from '../../../utils/RosterWebContext';
export default function Testing(props){
    let [contextValue,updateContext]=useContext(RosterWebContext);

    useEffect(()=>{
        console.log(contextValue.rosterList);
    },[contextValue])

    return(
        !!contextValue.rosterList?(
          <tbody>
          </tbody>
        ):(
        <span>Loading Roster</span>
       )
    )
}
brein
  • 1,409
  • 9
  • 11