Im trying to simulate breathing in a React Native app, the console log of the breathing in breathing out seems to work okay, however the Text never updates on the screen. it just sits on 'IN'
I'm new to react and struggling to find a solution. I tried using useState in stead of useRef for the current breathing status and it still does not update and the console does not work as expected when using useState.
useRef version
import React from 'react'
import { useState, useRef, useEffect } from 'react'
import { SafeAreaView } from 'react-native'
import { Layout, Text, Button } from '@ui-kitten/components'
const HomeScreen = () => {
const [sessionStarted, setSessionStarted] = useState(false)
const breathDoing = useRef('STOP');
const doNext = () => {
console.log('doNext')
switch(breathDoing.current) {
case 'IN':
console.log('We are breathing in we should breath out')
breathOut()
break
case 'OUT':
console.log('We are breathing out we should breath in')
breathIn()
break
case 'STOP':
console.log('We should stop breathing, yikes')
break
}
}
const breathIn = () => {
console.log('In breath in')
breathDoing.current = 'IN'
setTimeout(() => {
doNext()
}, 1000)
}
const breathOut = () => {
console.log('In breath out')
breathDoing.current = 'OUT'
setTimeout(() => {
doNext()
}, 1000)
}
const breathSession = () => {
console.log('breathSession');
setSessionStarted(true)
breathIn()
}
const stopBreathSession = () => {
console.log('stopBreathSession');
setSessionStarted(false)
breathDoing.current = 'STOP'
}
const BreathOutput = (props) => {
return <Text>{props.doing}</Text>
}
const handleSessionButton = () => {
if (sessionStarted) {
stopBreathSession()
} else {
breathSession()
}
}
return (
<>
<SafeAreaView>
<Layout level="1">
{sessionStarted ?
<>
<BreathOutput doing={breathDoing.current} />
</>
: null}
<Button onPress={() => handleSessionButton()}>
{sessionStarted ? 'stop' : 'start'}
</Button>
</Layout>
</SafeAreaView>
</>
)
}
export default HomeScreen
the console shows correct output:
We are breathing in we should breath out
In breath out
doNext
We are breathing out we should breath in
In breath in
doNext
We are breathing in we should breath out
In breath out
EDIT
useState version:
const [sessionStarted, setSessionStarted] = useState(false)
const [breathDoing, setBreathDoing] = useState('STOP')
const doNext = () => {
console.log('doNext')
switch(breathDoing) {
case 'IN':
console.log('We are breathing in we should breath out')
breathOut()
break
case 'OUT':
console.log('We are breathing out we should breath in')
breathIn()
break
case 'STOP':
console.log('We should stop breathing, yikes')
break
}
}
const breathIn = () => {
console.log('In breath in')
setBreathDoing('IN')
setTimeout(() => {
doNext()
}, 1000)
}
const breathOut = () => {
console.log('In breath out')
setBreathDoing('OUT')
setTimeout(() => {
doNext()
}, 1000)
}
const breathSession = () => {
console.log('breathSession');
setSessionStarted(true)
breathIn()
}
const stopBreathSession = () => {
console.log('stopBreathSession');
setSessionStarted(false)
setBreathDoing('STOP')
}
const BreathOutput = (props) => {
return <Text>{props.doing}</Text>
}
const handleSessionButton = () => {
if (sessionStarted) {
stopBreathSession()
} else {
breathSession()
}
}
return (
<>
<SafeAreaView>
<Layout level="1">
{sessionStarted ?
<>
<BreathOutput doing={breathDoing} />
</>
: null}
<Button onPress={() => handleSessionButton()}>
{sessionStarted ? 'stop' : 'start'}
</Button>
</Layout>
</SafeAreaView>
</>
)
The text stays as 'IN'
and the console outputs
breathSession
In breath in
doNext
We should stop breathing, yikes