SetState не работает после мутации GraphQL - PullRequest
0 голосов
/ 10 марта 2020

Если мутация прошла успешно, я пытаюсь setAdded до true в .then of `` `submitForm ()` `. Если это правда, я хочу показать сообщение от SuccessfulMessage (). Однако, когда я регистрирую значение добавленного, я вижу ложь.

Поскольку 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>
  );
}

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Ваш console.log() сразу после вызова setAdded не будет отображать true, так как обновления состояния асинхронны c и будут видны только при следующем рендере. Также ваш SuccessMessage никогда не будет запущен, потому что вы не предоставили никаких зависимостей для вашего useEffect(). Это означает, что он будет вызываться только после монтирования

. Вам нужно добавить added в список зависимостей:

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

Но на самом деле я не вижу причин для его запуска в useEffect в любом случае. Почему бы просто не вызвать его в обработчике мутаций?

Также, если вы уже используете хуки, вы можете использовать useMutation.

Также вы не можете вернуть JSX из обработчик Это ничего не сделает. Как должен реагировать даже знать, где отображать ваши <Typography>User Added</Typography>? Вы должны отобразить все в самом компоненте в зависимости от состояния.

0 голосов
/ 10 марта 2020

Извините, но ...

... это выглядит как отличный пример неправильного реагирования ... результат пропуска базовых c учебных пособий, документов и смешивания случайных устаревших примеров .

  • asyn c природа useStatesetState) - вы не можете ожидать обновления значения;
  • с использованием useEffect param без знания того, как это влияет на поведение;
  • 'useEffect' вообще не требуется;
  • возврат компонентов из обработчика событий вместо [условно управляемых данными] рендеринг;
  • если используется useMutation, вам не нужно передавать мутацию в качестве параметра обработчику события;
  • вы используете Formik (с проверкой полей), а затем проверяете параметры (поля) в обработчик просто не нужен;
  • вы можете просто использовать variables: { ...state }, если имена переменных переменных совпадают;
  • Formik управляет значениями, вам не нужно дублировать это, используя локальное состояние - есть причина?;
  • У Formik тоже есть хуки;) используйте useFormik();
  • ... обработчики событий, привязка ...
...