1

useEffect doesn't trigger on second change, but triggers twice on launch (React hooks and apollo-graphql hooks). In console.logs I described when the changes are triggered and when not. I don't have any more clue to add.

Here's my page (Next.js pages)

import React, { useEffect, useState } from 'react'
import Calendar from '../components/Calendar';
import { useHallsQuery } from '../generated/graphql';
const schedule = () => {

  const { data, loading, error, refetch:refetchSessions } = useHallsQuery();

  const [sessions, setSessions] = useState([] as any);

  const [owners, setOwners] = useState([] as any);
  

  useEffect(() => {
    console.log('On launch trigger twice, on first change trigger once, on second doesn't trigger and later trigger correctly, but it's one change delay');
    if(loading === false && data){
      const colors: any = [
        '#FF3333',
        '#3333FF',
        '#FFFF33',
        '#33FF33',
        '#33FFFF',
        '#9933FF',
        '#FF9933',
        '#FF33FF',
        '#FF3399',
        '#A0A0A0'
      ];
      let pushSessions:any = [];
      let owners:any = [];
      data?.halls?.map(({sessions, ...o}, index) =>{
        owners.push({id:o.id,
        text:o.name,
        color: colors[index%10]});
        sessions.map((session:any) => {
          pushSessions.push({...session,
            ownerId: o.id});
        })
    })
        setSessions(pushSessions);
        setOwners(owners);
    }
}, [loading, data])

    if (loading) return <div>Loading...</div>
    if (error) return <div>Error: {error.message}</div>

  return (
    <div>
      <Calendar sessions={sessions} owners={owners} refetchSessions={refetchSessions} />
    </div>
  )
}

export default schedule

and my component part where I get props and trigger refetchSessions.

    const Calendar = (props: any) => {
      let { sessions, owners, refetchSessions } = props;
    
      const [moveSession] = useMoveSessionMutation();
    ...
    
    const commitChanges = ({ added, changed, deleted }: any) => {
    
        if (added) {
       //
        }
        if (changed) {
           console.log('trigger on all changes! Correct')
          const id = Object.keys(changed)[0];
            moveSession({variables:{
              input: {
                id: parseInt(id),
                ...changed[id]
              }
            }, refetchQueries: refetchSessions
          })
        }
    if (deleted !== undefined) {
      // 
    }

  };

return (

// Some material-ui components and @devexpress/dx-react-scheduler-material-ui components in which commitChanges function is handled

)
export default Calendar;

Hook was generated with graphql-codegen(generated/graphql.tsx):

   export function useHallsQuery(baseOptions?: Apollo.QueryHookOptions<HallsQuery, HallsQueryVariables>) {
            return Apollo.useQuery<HallsQuery, HallsQueryVariables>(HallsDocument, baseOptions);
          }
    export function useHallsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<HallsQuery, HallsQueryVariables>) {
              return Apollo.useLazyQuery<HallsQuery, HallsQueryVariables>(HallsDocument, baseOptions);
            }
    export type HallsQueryHookResult = ReturnType<typeof useHallsQuery>;

and here's the schema(graphql/hall.graphql):

query Halls {
  halls {
    id
    name
    sessions{
      id
      title
      startDate
      endDate
    }
  }
}
Wiktor Kujawa
  • 595
  • 4
  • 21
  • Both of your dependencies [loading, data] come from useHallsQuery. Is it possible that you are mutating data in that hook? Please update your post to include that hook. Also I don’t think you want to have sessions and owners as state variables. They can just be constants derived from data. – Linda Paiste Mar 16 '21 at 17:21
  • I did a test with delete mutation, and it works correctly. – Wiktor Kujawa Mar 16 '21 at 19:16
  • Does it help if you delete the `useEffect` and `useState` from `sessions` (needs to be uppercase `Sessions`), and replace it with `const owners = data?.halls?.map(({ name, id }, index) => ({ id, text: name, color: colors[index % 10] })) || []` and `const sessions = data?.halls?.map( ({sessions, id}) => sessions.map( session => ({...session, ownerId: id})) ).flat(1) || [];`? You can use `useMemo` on those mappings for perfomance if it works. – Linda Paiste Mar 16 '21 at 19:33
  • Ok, it still doesn't work, I even past it directly to Calendar component. For example delete works everytime, and in AppointmentForm(calendar component) changing data also doesn't work(it didn't even reach the server(resolvers)), but delete works. So the problem is that it just need too many time to proceed. – Wiktor Kujawa Mar 16 '21 at 19:52

0 Answers0