javascript - 正确使用 onCompleted 进行 GraphQL 突变

标签 javascript reactjs typescript graphql apollo

我想先运行查询。查询返回一个 id,然后该 id 是突变所需要的。目前,这两项内容从 handleSubmit() 运行的顺序存在问题。如果突变成功,控制台应该打印 console.log('Checking'); 但这种情况不会发生。我在控制台上得到的唯一输出是Id是什么,并且该值可能是我之前的尝试之一中存储的内容。如果 id 是从这一轮特定的查询中派生的,我会在日志上看到 Working,但这也不会发生。

 const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery, {
    variables: {
      where: { email: friendEmail.toLocaleLowerCase() },
    },
    onCompleted: () => getFriendId(),
  });



  const [
    createUserRelationMutation,
    {
      data: addingFriendData,
      loading: addingFriendLoading,
      error: addingFriendError,
    },
  ] = useCreateUserRelationMutation({
    variables: {
      input: {
        relatedUserId: Number(id),
        type: RelationType.Friend,
        userId: 5,
      },
    },
    onCompleted: () => addFriend(),
  });
  const getFriendId = () => {
    console.log('Working');
    if (data) {
      console.log(data);
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
      }
    } else {
      if (error) {
        setErrorMessage(error.message);
      }
    }
  };

  const addFriend = () => {
    console.log('Whats the Id', Number(id));
    if (addingFriendData) {
      console.log('Checking');
      console.log(addingFriendData);
    }
    if (addingFriendError) {
      console.log('errorFriend', addingFriendError.message);
      setErrorMessage(addingFriendError.message);
    }
  };

 const handleSubmit = () => {
    loadUsers();
    createUserRelationMutation();
  };

在此之前,我正在尝试这样做:

const [id, setId] = useState('');
const [friendEmail, setFriendEmail] = useState('');

const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);
const [createUserRelationMutation, { data: addingFriendData, loading: addingFriendLoading, error: addingFriendError }] = useCreateUserRelationMutation();

const getFriendId = () => {
    console.log('Email', friendEmail.toLocaleLowerCase());
    loadUsers({
      variables: {
        where: { email: friendEmail.toLocaleLowerCase() },
      },
    });
    if (data) {     
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);      
    } 
    addFriend();
  };

  const addFriend = () => {
    console.log('Whats the Id', Number(id));
       createUserRelationMutation({
        variables: {
               input: {relatedUserId: Number(id), type: RelationType.Friend, userId: 7 }
            },
       });
       if (addingFriendData){
         console.log('Checking')
         console.log(data);
       }
       if(addingFriendError){
         console.log('errorFriend', addingFriendError.message);
         setErrorMessage(addingFriendError.message);
       }
  }


const handleSubmit = () =>
    {getFriendId();};

但是,在这种情况下,id 和其他状态的值没有及时更新。我在 getFriendId() 中运行一个 graphql 查询,返回一个 id,然后是一个突变(在 addFriend() 中,它使用 id 以及一个输入(电子邮件)用户输入的内容。问题是,在第一次尝试时,突变工作正常并且具有正确的值。但是,当我更改输入上的电子邮件地址并再次运行查询/突变时,我之前尝试的值正在使用中。

在第二次尝试中,突变仍然使用我们在第一次尝试中获得的 id。

编辑:

onCompleted: (data) => getFriendId(data),

 const getFriendId = (data: any) => {
    console.log('Working');
    if (data) {
      console.log(data);
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
      }

更新的代码:

 const [friendEmail, setFriendEmail] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  const [loadUsers, { loading, data, error }] = useLazyQuery(LoadUsersQuery);

  const [
    createUserRelationMutation,
    {
      data: addingFriendData,
      loading: addingFriendLoading,
      error: addingFriendError,
    },
  ] = useCreateUserRelationMutation();


 const getFriendId = () => {
    console.log('Email', friendEmail.toLocaleLowerCase());
    loadUsers({
      variables: {
        where: { email: friendEmail.toLocaleLowerCase() },
      },
    });
    if (data) {
      if (data.users.nodes.length == 0) {
        console.log('No user');
        setErrorMessage('User Not Found');
      } else {
        console.log('ID', data.users.nodes[0].id);
        setId(data.users.nodes[0].id);
        addFriend(data.users.nodes[0].id); 

      }
    } else {
      console.log('No data');
      if (error) {
        setErrorMessage(error.message);
      }
    }
    //addFriend();
  };

  const addFriend = (idd: any) => {
    console.log('Whats the Id', Number(idd));
       createUserRelationMutation({
        variables: {
               input: {relatedUserId: Number(idd), type: RelationType.Friend, userId: 9 }
            },
       });
       if (addingFriendData){
         console.log('Checking')
         console.log(data);
       }
       if(addingFriendError){
         console.log('errorFriend', addingFriendError.message);
         setErrorMessage(addingFriendError.message);
       }
  }

    const handleSubmit = () =>
    {
    getFriendId();
    };

最佳答案

您不需要状态来存储 ID,而是将 Id 传递给 addFriend 方法,如下所示

    const [friendEmail, setFriendEmail] = useState('');
    const [errorMessage, setErrorMessage] = useState('');

    const _onLoadUserError = React.useCallback((error: ApolloError) => {
        setErrorMessage(error.message);
    }, []);

    const [
        createUserRelationMutation,
        {
            data: addingFriendData,
            loading: addingFriendLoading,
            error: addingFriendError,
            called: isMutationCalled
        },
    ] = useCreateUserRelationMutation();

    const addFriend = React.useCallback((idd: Number) => {
        console.log('Whats the Id', idd);
        createUserRelationMutation({
            variables: {
                input: { relatedUserId: idd, type: RelationType.Friend, userId: 9 }
            }
        });
    }, [createUserRelationMutation]);

    const getFriendId = React.useCallback((data: any) => {
        console.log('Email', friendEmail.toLocaleLowerCase());
        if (data) {
            if (data.users.nodes.length == 0) {
                console.log('No user');
                setErrorMessage('User Not Found');
            } else {
                console.log('ID', data.users.nodes[0].id);
                addFriend(Number(data.users.nodes[0].id));

            }
        }
    }, [friendEmail, addFriend]);

    const [loadUsers] = useLazyQuery(LoadUsersQuery, {
        onCompleted: getFriendId,
        onError: _onLoadUserError
    });

    const handleSubmit = React.useCallback(() => {
        loadUsers({
            variables: {
                where: { email: friendEmail.toLocaleLowerCase() },
            }
        });
    }, [loadUsers, friendEmail]);

    if (!addingFriendLoading && isMutationCalled) {
        if (addingFriendData) {
            console.log('Checking')
            console.log(data);
        }
        if (addingFriendError) {
            console.log('errorFriend', addingFriendError.message);
            setErrorMessage(addingFriendError.message);
        }
    }

Update

我已经更新了上面的代码,请引用。我假设 useCreateUserRelationMutation 不接受选项作为参数,如果它接受选项,那么您可以使用 onCompleted 和 onError 就像 loadUsers 查询一样。

关于javascript - 正确使用 onCompleted 进行 GraphQL 突变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61526596/

相关文章:

javascript - 在单页应用程序中处理文本编辑器的 Ctrl+Z(撤消/重做)

javascript - Node.js 播放声音 : TypeError: Cannot read property 'play' of undefined

reactjs - Jest 错误 react 组件上出现意外标记

javascript - react 。如何从父组件调用组件的方法

javascript - 如何从 typescript 中的字符串中减去日?

node.js - typescript :req.user 可能是 'undefined' - express 和 passport js

javascript - 谷歌地图方向渲染替代路线如何选择所需路径

javascript - 为什么向下滚动到底部页面时会重复数据?

javascript - 调用 `this.setState()` 会中断对 componentWillReceiveProps 中的 prop 进行流类型检查

reactjs - JSX 属性中禁止使用 Lambda,因为它们会影响渲染性能