K
K
kxnkxv2021-01-12 18:06:58
React
kxnkxv, 2021-01-12 18:06:58

Why is the query being executed when re-rendering components?

Steps to reproduce the bug: 1.
Enter an unregistered phone number (+ you can not enter a password)
2. Press the enter button 3.
Erase one character from the input with the phone number "enter") the state changes and for some reason a request occurs. Why does a request occur? After all, the request is in no way connected with the life cycle of the component, it should not be called when redrawing and when changing the state as well.



The code

import React, {Component} from 'react';
import {Button, Card, Elevation, FormGroup, InputGroup, Tooltip} from "@blueprintjs/core";
import classes from "../regByPhone/regByPhone.module.scss";
import {Layout} from "../common";
import classesCommon from "../common/common.module.scss";
import {Link} from "react-router-dom";
import {gql, useLazyQuery} from "@apollo/client";

class Login extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      phone: "",
      password: "",
      formErrorText: ""
    };
  }

  handleLoginPhoneInput({target: {value: phone}}) {
    this.setState({phone});
  };

  handleLoginLockClick() {
    this.setState((prevState) => ({
      showPassword: !prevState.showPassword,
    }));
  };

  render() {
    const {showPassword, phone, password, isFormNotValid} = this.state,
      {onAuth} = this.props;

    return (
      <Layout>
        <Card elevation={Elevation.TWO} className={classesCommon.card}>
          <FormGroup helperText={this.state.phoneErrorText}>
            <InputGroup
              className={classes.phone_input}
              large
              placeholder="Введите Ваш номер телефона"
              value={phone}
              onChange={this.handleLoginPhoneInput.bind(this)}
              maxLength={11}
            />
          </FormGroup>
          <FormGroup helperText={this.state.passwordErrorText}>
            <InputGroup
              className={classes.pass_input}
              large
              placeholder="Введите пароль"
              rightElement={<LockButton showPassword={showPassword} onClick={this.handleLoginLockClick.bind(this)}/>}
              type={showPassword ? "text" : "password"}
              value={password}
              onChange={this.handleLoginPasswordInput.bind(this)}
            />
          </FormGroup>
          <p>{this.state.formErrorText}</p>
          <Link to="/registration-by-phone">Регистрация</Link>
          <LoginButton phone={phone} password={password} isFormNotValid={isFormNotValid} onAuth={onAuth}/>
        </Card>
      </Layout>
    );
  }
}

const LOGIN = gql`
    query login($login: String!, $pwd: String!) {
        login(login: $login, pwd: $pwd) {
            id, userName, surname, firstname, middlename, email, phone
        }
    }
`;

function LoginButton({phone, password, isFormNotValid, onAuth}) {

  const [getLogin, {loading, data}] = useLazyQuery(LOGIN, {variables: {login: phone, pwd: password}});

  if (data?.login != null) {
    onAuth(data.login)
  }

  return <Button
    className={classes.enter}
    large
    disabled={isFormNotValid}
    onClick={getLogin}
  >
    Войти
  </Button>
}

export default Login;

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
kxnkxv, 2021-01-13
@kxnkxv

5ffef6fb59eee003775756.png
Overall. Here is the solution.

N
Nikolai Lanets, 2021-01-13
@Fi1osof

It is unlikely that there is a graph bug.
Most likely you have a logical error somewhere. Why do I say so? Because you use != in data?.login != null (not a strict comparison). Try to use non-strict comparison as much as possible, otherwise you get used to inaccuracies. If in this case you want to explicitly compare non-strictly, then at least write if(!data?.login). Although this is also not a strict comparison, it is more accepted this way.
Second, you have
if (data?.login != null) {
onAuth(data.login)
}
being executed on every render. Since your login is not empty at this moment, the onAuth method is triggered every time. Go see what's in it.
Thirdly, look at the config of the created Apollo client, maybe you have set the default fetchPolicy: 'network-only' or something like that.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question