pseudostack
pseudostack

Reputation: 21

Handling state when making multiple function calls in React with hooks as a parameter

I'm trying to send API calls using the state of one of my hooks as a payload in the HTTP request. The issue I'm having is that the hook being asynchronous is causing irritating behaviour. The two issues I'm facing are:

  1. The state is one step behind when sending the payload, so the HTTP request is going through with my initialised data which I don't want to send.
  2. The component is not re-rendering with the updated state.

Some of my implementation code includes:

Function definition for get request that sets state to the role i'm using

    function roleSelector(role_id: string) {
        webHelpers.get('/api/worker/role/' + role_id, environment, 'api', token, (data: any) => {
            setLocalRole(data);
        });
    }

Function that handles the changes in component which trigger the cycle and call the above function as well as send off the request after.

    function handleAuxChange(aux_value: boolean, role_id: string) {
        roleSelector(role_id);
        localRole.skills = [];
        localRole.allow_aux = !aux_value;
        updateRole(localRole);
    }

Function that sends off the HTTP POST request:

    function updateRole(role: UserRole) {
        let skills = [...role.skills];
        role.details.forEach(s => {
            skills.push({ skill_id: s.skill.id, level_id: s.level.id })
        });
        role.skills = skills;
        webHelpers.post('/api/worker/role', environment, 'api', role, token, (data: any) => {
            if (data.status === undefined) {
                enqueueSnackbar('role successfully set to active!', { 'variant': 'success' });
            }
            else {
                console.log(role);
                enqueueSnackbar(`${data.status}: Unable to apply changes to the role`, { 'variant': 'error' })
            }
        });
    }

Is there something in my implementation that i'm doing/not doing that's leading me to be a step behind in state? I've tried writing in a useEffect hook too with localRole as an entry in the default dependency array but this was no help for me either.

Upvotes: 0

Views: 43

Answers (1)

Keith
Keith

Reputation: 24181

You could make roleSelector return the data. And the handleAuxChange can use the info directly.

eg.

function roleSelector(role_id: string, cb: (data:any) => void) {
   return webHelpers.get('/api/worker/role/' + role_id, environment, 'api', token, (data: any) => {
     setLocalRole(data);
     cb(data);
   });
}

function handleAuxChange(aux_value: boolean, role_id: string) {
   roleSelector(role_id, localRole => {
     localRole.skills = [];
     localRole.allow_aux = !aux_value;
     updateRole(localRole);
   });
}

Upvotes: 2

Related Questions