Skip to content

Fetching data in react returns “undefined” at first time

I have a function component that I control user login with react. According to the username and password entered in the input, if the value returned from the API is true, it redirects to another page, if false, it stays on the same page. When I press the button when the username and password are correct, the first value is It returns undifined , but when I press the button for the second time, it returns true and redirects to another page.

console.log(isUser); // When I check, it shows undefined even though the values ​​for the first name and password are full, but when I press the button again, it returns true if the username and password are correct.

What is the reason of this?

 export default function Login() {
      const [isUser, setUser] = useState();
      const [name, setName] = useState('');
      const [password, setPassword] = useState('');
      const [error, setError] = useState('');
    
      const history = useHistory();
      let control;
    
      function userControl() {
        debugger;
        let userService = new UserService();
        userService.getUserControl(name, password).then((result) => setUser(result.data.data));
        console.log(isUser);
    
        if (isUser == true) {
          history.push('/oee');
        } else {
          setUser(false);
          setError('Kullanıcı Adınız veya Şifreniz Hatalı');
          control = errorMessage();
        }
      }
    
      function errorMessage() {
        return (
          <div>
            <Message negative>
              <Message.Header>{error}</Message.Header>
            </Message>
          </div>
        );
      }
    
      return (
        <div>
          {control}
          <Grid textAlign="center" style={{ height: '70vh' }} verticalAlign="middle">
            <Grid.Column style={{ maxWidth: 450 }}>
              <Header as="h2" color="teal" textAlign="center">
                <Image style={{ height: 100, width: 200 }} src={ydclogo} />
              </Header>
              <Form size="large">
                <Segment stacked>
                  <Form.Input
                    fluid
                    icon="user"
                    iconPosition="left"
                    placeholder="User Name"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                  />
                  <Form.Input
                    fluid
                    icon="lock"
                    iconPosition="left"
                    placeholder="Password"
                    type="password"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                  />
                  <Button color="teal" fluid size="large" onClick={userControl}>
                    Login
                  </Button>
                </Segment>
              </Form>
              <Message>L3 RAPORLAMA SİSTEMİ</Message>
            </Grid.Column>
          </Grid>
        </div>
      );
    }

Answer

userService.getUserControl is async operation. To be able to use this response you should wrap your code in then() callback. But setting the state value using useState is also async operation and there is no guarantee that you will be able to read the actual value right after calling setUser. You could do something like that:

userService.getUserControl(name, password).then((result) => {
        const user = result.data.data
        setUser(user)

        if (user == true) {
          history.push('/oee');
        } else {
          setUser(false);
          setError('Kullanıcı Adınız veya Şifreniz Hatalı');
          control = errorMessage();
        }
});