首页 > 解决方案 > GraphQL 突变后 SetState 不起作用

问题描述

如果突变成功,我会尝试setAddedtrue.then 的 ```submitForm()`` 中。如果这是真的,我想显示来自 SuccessMessage() 的消息。但是,当我记录添加的值时,我一直看到错误。

由于added没有更改为true。突变成功时,我看不到任何消息。为什么不改变?

export default function AddUserPage() {
  const [state, setState] = useState({
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    phoneNumber:'',
    loggedIn: false,
  });  

  const [added, setAdded] = useState(false);

  function SuccessMessage(){
    if (added)
    {
      console.log('User Added');
      return (
      <Typography>
        User Added
        </Typography>)
    }
  }

  useEffect(() => {
    if(added){
      SuccessMessage();
    }
  },[] );

function submitForm(AddUserMutation: any) {
    const { firstName, lastName, email, password, phoneNumber } = state;
    if (firstName && lastName && email && password && phoneNumber) {
      AddUserMutation({
        variables: {
          firstName: firstName,
          lastName: lastName,
          email: email,
          password: password,
          phoneNumber: phoneNumber,
        },
      }).then(({ data }: any) => {
        setAdded(true);
        console.log('doing', added);
        console.log('ID: ', data.createUser.id);
        console.log('doing', added);
      })
        .catch(console.log)
    }
  }

  return (
    <Mutation mutation={AddUserMutation}>
      {(AddUserMutation: any) => (
        <div>
          <PermanentDrawerLeft></PermanentDrawerLeft>
          <Formik
            initialValues={{ firstName: '', lastName: '', email: '', password: '', phoneNumber: '' }}
            onSubmit={(values, actions) => {
              setTimeout(() => {
                alert(JSON.stringify(values, null, 2));
                actions.setSubmitting(false);
              }, 1000);
            }}
            validationSchema={schema}
          >
            {props => {
              const {
                values: { firstName, lastName, email, password, 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(AddUserMutation);SuccessMessage()}}>
                    <div>
                      <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")}
                      />
                      <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")}
                      />
                      <Button
                      type="submit"
                      disabled={!isValid || !email || !password}
                      >
                        Add User</Button>
                    </div>
                  </form>
                </div>
              )
            }}
          </Formik>
        </div>
      )
      }
    </Mutation>
  );
}

标签: javascriptreactjstypescriptgraphqlreact-hooks

解决方案


您的console.log()直接调用后setAdded不会显示true,因为状态更新是异步的,仅在下一次渲染时可见。此外,您SuccessMessage将永远不会被触发,因为您没有为您的useEffect(). 这意味着它只会在挂载后被调用

您需要添加added到依赖项列表:

useEffect(() => {
    if(added){
        SuccessMessage();
    }
},[added]);

但实际上我看不出有任何理由触发它useEffect。为什么不在突变处理程序中调用它呢?

此外,如果您已经在使用钩子,则可以使用useMutation.

您也不能从处理程序返回 JSX。它不会做任何事情。应该如何反应甚至知道在哪里显示你的<Typography>User Added</Typography>?您必须根据状态渲染组件本身的所有内容。


推荐阅读