I am trying to update state to show an ActivityIndicator while an asynchronous call is being made.
What is the correct way of doing this to ensure IsLoading(true)
and setResult(null)
will happen before the the async call?
In the code below setIsLoading
is not actually updated before the async call and thus the ActivityIndicator does not appear on the UI. I realize why this is the case (here) I just don't know the recommended way to do actually ensure the ActivityIndicator shows before the async call is made.
Please help. What is the correct way to do this in react?
const MyScreen = () => {
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState(null);
const handlePress = async () => {
setResult(null); // reset result
setIsLoading(true); // show activity indicator
const result = await MyAsyncFunc(); // native modules function
setResult(result);
setIsLoading(false); // turn off activity indicator
}
return (
<View style={styles.container}>
<MyButton title="Run" handlePress={handlePress} disabled={isLoading} />
{isLoading && <ActivityIndicator size="large" color="#00ff00" />}
<Text>{result}</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
})
CodePudding user response:
Can you try using just one state? no need isLoading
for this I think.
try this
{!result && <ActivityIndicator size="large" color="#00ff00" />}
EDIT: lets utilize useEffect to listen to if isLoading is true
...
useEffect(() => {
async function load (){
if (isLoading) {
const result = await MyAsyncFunc(); // native modules function
setResult(result);
setIsLoading(false); // turn off activity indicator
}
}
load()
}, [isLoading])
const handlePress = () => {
setResult(null); // reset result
setIsLoading(true); // show activity indicator
}
CodePudding user response:
Try adding useEffect
and set isLoading
false on changing of result
dependency there, like this:
const MyScreen = () => {
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState(null);
const handlePress = async () => {
setResult(null); // reset result
setIsLoading(true); // show activity indicator
const result = await MyAsyncFunc(); // native modules function
setResult(result);
//setIsLoading(false); // turn off activity indicator
}
useEffect(() => {
if(result && isLoading){
setIsLoading(false);
}
}, [isLoading, result])
return (
<View style={styles.container}>
<MyButton title="Run" handlePress={handlePress} disabled={isLoading} />
{isLoading && <ActivityIndicator size="large" color="#00ff00" />}
<Text>{result}</Text>
</View>
)
}
Hope this works for you