React Native: Why is useState setter not causing a re-render?

As a beginner in react and javascript, I am facing an issue with showing an ActivityIndicator while logging in a user. The setIsLoading method doesn't seem to change the state and trigger a rerender. When the handleLogin method is called on a button click, useEffect isn't being executed as expected, as it's not printed to the console. Additionally, despite setting isLoading to true, console.log(isLoading) still displays false. Interestingly, when I commented out the firebase section, everything worked fine. If anyone can shed light on this behavior, I would greatly appreciate it. Thank you.

import React, { useState, useEffect } from 'react'
import firebase from '../firebase'
import { ActivityIndicator, StyleSheet, Text, TextInput, View, Button} from 'react-native'
export default function LoginScreen({navigation}) {
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')
    const [errorMessage, setErrorMessage] = useState(null)
    const [isLoading, setIsLoading] = useState(false)
    const [showLoader, setShowLoader] = useState(false)

    useEffect(() => {
        setShowLoader(isLoading)
        console.log('useEffect')
    },[isLoading])

    const handleLogin = () => { 
        setIsLoading(true)
        console.log(isLoading)

        firebase.auth().signInWithEmailAndPassword(email, password)
        .then(() => { navigation.navigate('Home')})
        .then(setIsLoading(false))
        .catch((error) => {setErrorMessage(error.message)})

        console.log('handleLogin')
    }
    return (
      <View style={styles.container}>
        <Text>Login</Text>
        {errorMessage &&
          <Text style={{ color: 'red' }}>
            {errorMessage}
          </Text>}
        <TextInput
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Email"
          onChangeText={email => setEmail(email)}
          value={email}
        />
        <TextInput
          secureTextEntry
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Password"
          onChangeText={password => setPassword(password)}
          value={password}
        />
        <Button title="Login" onPress={handleLogin} />
        <Button
          title="Don't have an account? Sign Up"
          onPress={() => navigation.navigate('SignUp')}
        />
        {
            showLoader && <ActivityIndicator/>
        }   
      </View>
    )
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  textInput: {
    height: 40,
    width: '90%',
    borderColor: 'gray',
    borderWidth: 1,
    marginTop: 8
  }
})

Edit: After some exploration, I realized that the useEffect is only triggered after the handleLogin method completes its execution. This means that isLoading is set to true but then reverted back to false after the signin process, rendering the useEffect ineffective. Any suggestions or insights on how to resolve this sequence of events would be highly appreciated. Thank you!

Answer №1

It appears that you may be moving away from the screen before setIsLoading has a chance to execute, although it's difficult to pinpoint this as the issue without seeing the entire code.

The reason why console.log(isLoading) is false is due to the asynchronous nature of useState. When the next line of code is reached, setIsLoading is still unresolved because it is a promise.

A more concise approach for this line of code

isLoading? setShowLoader(true) : setShowLoader(false)
would be to simply use setShowLoader(isLoading)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the values of a particular key from your Django queryset JSON data and then seamlessly send them over to VueJS

I recently developed a web app using Django2 with Vue for the frontend. I encountered an issue in passing all values of a specific key from JSON data to a JavaScript dictionary value on the frontend. Despite trying to use the += operator to add the data, I ...

Is there a way to efficiently return an array of object and nested object keys with their full paths through recursion

My grasp of JS is still in its early stages, so understanding how the stack and recursion function can be challenging for me at this point. The task at hand involves displaying an array of object keys, including the parent object name if the object is nest ...

Creating a dual-column checkbox design with CSS only

I'm working with a dynamically generated form element that can only be styled using CSS. I need help achieving a specific layout without making any HTML changes, except for the classes. The "element" and "formField" classes are common and cannot be mo ...

Guidance on uploading a file with AJAX in PHP following the display of a Sweet Alert

I am currently facing an issue with inserting a file input (images) into my database. When I try to insert it, the value returned is empty. Below is the script I am using: <script> $("#insertform").on('submit',(function(e) { ...

Webpack 2.7.0 throws an error: "Unexpected parameter: theme"

At the moment, I am on webpack 1.16.0 and using --theme as an argument to set the output path and plugin paths. The command appears as: rimraf dist && webpack --bail --progress --profile --theme=<name of theme> However, as I try to upgrade ...

Updating a page in ReactJS after retrieving data: A step-by-step guide

Just starting out with ReactJS and attempting to create an interactive comments section based on a design from frontendmentor.io. However, my App component is not displaying the expected content. Here is the code for my App component: function App() { ...

Automated tools and frameworks for the testing of website performance

Hello, I have a website that heavily relies on AJAX for server communication. I am looking to conduct performance and stress testing using automated scripts. Can you provide any suggestions or recommendations? I am specifically interested in the functiona ...

Enhance Data3 Sankey to disperse data efficiently

There are a few instances where the D3 Sankey spread feature is showcased here. However, it seems that this specific function is not included in the official D3 Sankey plugin. Is there anyone who can assist me in obtaining the code for the Spread function ...

Scrolling through a list in Angular using cdk-virtual-scroll-viewport while selecting items via keyboard input

Looking to implement a customized Autocomplete feature. As the user begins typing, a small window should appear with selectable options. I want users to have the ability to navigate and select an option using their keyboard. For instance: - User types "H ...

React Image Slider not loading pictures

Can someone help me troubleshoot why my images are not displaying in the slider on my homepage? I have set up the slider using React Slideshow Image, but the images are not showing up for some reason. I am also wondering if anyone knows of any full-screen ...

Prevent the propagation of a particular CSS class's inheritance

I need to make modifications to an existing HTML5 app that features two unique themes. Here's an example of the current structure: <body class="theme1 theme2"> <div id="div1">I'm satisfied with both themes</div> <di ...

What is the best way to upload a file to a server while working with Vue.js in the Filemanager plugin, or how can I access a global function

How can I upload a file to the server using Vue.js in the Filemanager plugin? I have tried multiple methods and the console log shows that the upload was successful, but I am not able to see any files on the server. Does anyone know what could be wrong? & ...

The POST request to the localhost API endpoint resulted in a 404 Not Found error

Whenever I try to send a POST request to "/api/auth/signup" in my JavaScript application, I keep getting a 404 Not Found error. My goal is to create a MERN application for a Modern Real Estate Marketplace. This is the code snippet causing the is ...

Requirements for two buttons

One of the requirements I have is that if the user chooses Radio button A, then a specific button should be displayed. <input type="button" disabled="disabled" name="next" value="Proceed to Payment" onclick="window.location='shipping.php#openModal ...

AngularJS Compile directive allows you to specify functions that you want to run in

Can someone assist me in understanding how to call an external function from a built-in compile directive? Here is a code example: http://plnkr.co/edit/bPDaxn3xleR8SmnEIrEf?p=preview This is the HTML: <!DOCTYPE html> <html ng-app="app"> ...

Failed to retrieve information using a custom header in the HTTP request

My AngularJS code works well without the header option. $http.get(env.apiURL()+'/banks', { headers: { 'Authorization': 'Bearer '+localStorageService.get('access_token') } }) Here is the request: OP ...

Is there a way to deactivate a button upon clicking and then substitute it with a new button that serves a different purpose in AngularJS?

Is there a way to deactivate a button once clicked and substitute it with another button that performs a different task using AngularJS? Here is the button in question: <button type="submit" class="btn btn-small btn-default" ng-disabled="isteam==0 || ...

I am attempting to send an array from the controller to JavaScript using AJAX, but instead of returning as an array, it is being returned as a string

Here is the code snippet from my controller: <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class AjaxController extends Controller { public function s ...

Javascript - Error encountered when utilizing a for loop to insert a new column into an array

I have been utilizing an API to fetch data on various stocks, and I am attempting to include a column named "symbol" with the query values using the function insertColumn. However, I am encountering an error message that says (node:15732) UnhandledPromiseR ...

Tips for maintaining the navigation tab's consistent appearance

Whenever I click a button on the sidebar and the current tab is the second tab, the navigation bar switches to display the first tab. How can I prevent this switch and keep the second tab displayed when clicking a button on the sidebar? The code for this ...