调用 GraphQL 突变的 If/Else 条件

Posted

技术标签:

【中文标题】调用 GraphQL 突变的 If/Else 条件【英文标题】:If/Else Conditions for Calling GraphQL Mutations 【发布时间】:2020-06-27 13:20:34 【问题描述】:

我的updateUser 接受电子邮件输入并在后端更新该用户的firstName/lastName。目前,我的突变运行方式是,如果我只输入 firstName 并将 lastName 文本字段留空,在后端,lastName 将更改为 ''blank。

我想要一个方法,如果我提交的表单只有名字,只有名字应该更新,而姓氏保持不变。我无法弄清楚这些条件到底应该放在哪里以及如何放置。

更新用户页面:

export default function UpdateUserPage() 
  const [state, setState] = useState(
    firstName: '',
    lastName: '',
    email: '',
    phoneNumber:'',
  );  

  const [isSubmitted, setIsSubmitted] = useState(false);
  const [isAdded, setIsAdded] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  function StatusMessage() 

  function submitForm(UpdateUserMutation: any) 
    setIsSubmitted(true);
    const  firstName, lastName, email, phoneNumber  = state;
    if (email && (firstName || lastName || phoneNumber)) 
      UpdateUserMutation(
        variables: 
          firstName: firstName,
          lastName: lastName,
          email: email,
          phoneNumber: phoneNumber,
        ,
      ).then((data:any) => 
          setIsAdded(true);

      )
      .catch((error:  message: string; ) => 
        setIsAdded(false);
        setErrorMessage(error.message)
      )
    
  

  return (
    <Mutation mutation=UpdateUserMutation>
      (UpdateUserMutation: any) => (
        <div>
          <Formik
            initialValues= firstName: '', lastName: '', email: ''
            onSubmit=(values, actions) => 
              setTimeout(() => 
                alert(JSON.stringify(values, null, 2));
                actions.setSubmitting(false);
              , 1000);
            
            validationSchema=schema
          >
            props => 
              const 
                values:  firstName, lastName, email, phoneNumber ,
                errors,
                touched,
                handleChange,
                isValid,
                setFieldTouched
               = props;
              const change = (name: string, e: any) => 
                e.persist();
                handleChange(e);
                setFieldTouched(name, true, false);
                setState( prevState  => ( ...prevState, [name]: e.target.value )); 
              ;
              return (
                <div className='main-content'>
                  <form style= width: '100%'  
                  onSubmit=e => e.preventDefault();
                    submitForm(UpdateUserMutation);StatusMessage()>
                    <div>
                    <TextField
                        variant="outlined"
                        margin="normal"
                        id="email"
                        name="email"
                        helperText=touched.email ? errors.email : ""
                        error=touched.email && Boolean(errors.email)
                        label="Email"
                        value=email
                        onChange=change.bind(null, "email")
                      />
                      <br></br>
                      <TextField
                        variant="outlined"
                        margin="normal"
                        id="firstName"
                        name="firstName"
                        helperText=touched.firstName ? errors.firstName : ""
                        error=touched.firstName && Boolean(errors.firstName)
                        label="First Name"
                        value=firstName
                        onChange=change.bind(null, "firstName")
                      />
                      <br></br>
                      <TextField
                        variant="outlined"
                        margin="normal"
                        id="lastName"
                        name="lastName"
                        helperText=touched.lastName ? errors.lastName : ""
                        error=touched.lastName && Boolean(errors.lastName)
                        label="Last Name"
                        value=lastName
                        onChange=change.bind(null, "lastName")
                      />
                      <Button
                      type="submit"
                      disabled=!isValid || !email
                      >
                        Update User Info</Button>
                    </div>
                  </form>
                  <br></br>
                  isSubmitted && StatusMessage()
                </div>
              )
            
          </Formik>
        </div>
      )
      
    </Mutation>
  );

突变:

export const UpdateUserMutation = gql`
mutation UpdateUserMutation($email: String!, $firstName: String, $lastName: String)
  updateUser(email: $email, input: firstName: $firstName, lastName: $lastName)id,firstName

`;

在操场上,即使只通过了一个字段,突变也会起作用。在这种情况下,只有该字段被更改,其他字段保持不变。现在根据我现有的代码,不知道如何在前端实现。

【问题讨论】:

使用 relay.js relay.dev 是使用 [如上] 传递的空字符串的游乐场吗? 是的,playground 也可以使用空字符串@xadm 如果我已经在使用 Apollo,是否适合使用 Relay? @JuhilSomaiya 【参考方案1】:

您声称 Playground 调用的变异有效...在浏览器开发工具(网络选项卡)中比较请求 [详细信息]。

将“旧式”组件(&lt;Mutation /&gt;&lt;Formik /&gt;)与钩子混合[至少]不是一个好主意。使用useFormikuseMutation 钩子。

Formik 管理字段的值,然后无需在状态中管理它们。

【讨论】:

我想我之前误解了你的问题。在操场上,如果我在不传递 lastName 的情况下运行查询,那么它只会修改 firstName 并保持 lastName 不变。但是,在我的前端,我不确定如何实现不同的案例。我希望如果我只输入名字,则应该调用一个只有名字的突变。我说得通吗? @a125 您可以有条件地构造variables 对象...以variables = email ; 开始并有条件地(非空)定义其他属性...或者如果后端以null 的方式对其进行解释,则将其传递为你需要。

以上是关于调用 GraphQL 突变的 If/Else 条件的主要内容,如果未能解决你的问题,请参考以下文章

当用户连续执行多个graphql突变时防止竞争条件

从另一个突变中调用 GraphQL 突变?

如何从单个反应组件中调用多个 graphql 突变?

使用钩子从反应中调用 GraphQL 突变的正确方法

Apollo GraphQL:从服务器调用突变?

使用 Prisma 和 Apollo 调用多个 GraphQL 突变的正确方法是啥