I can’t update my notes state. When I first call updateNotes function it logs null array. But if I call it twice it’s loaded by the available values. How can I fix this?
const AddNote = ({navigation, route}) => {
const [title, setTitle] = useState('');
const [detail, setDetail] = useState('');
const [notes, setNotes] = useState([]);
function updateNotes() {
if (title === '' || detail === '') {
console.warn('Each input must have a value');
}
else {
// setId((prev) => prev + 1);
setNotes(prev => [...prev, {title: title, details:detail, color:color}]);
console.log(notes);
updateDoc(docRef, {
notes,
})
.then(() => {
console.log('UPDATED')
navigation.navigate('Notes');
})
}
}
return (...)
}
You can see the whole component file below.
Full Component:
import { Pressable, StyleSheet, Text, View, TextInput } from 'react-native'
import { Entypo } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import React, {useEffect, useState} from 'react'
// import { useSelector } from 'react-redux'
import { FontAwesome } from '@expo/vector-icons';
import { addDoc, serverTimestamp, doc, updateDoc } from 'firebase/firestore';
import { db, colRef } from '../firebase';
import ColorPalette from '../components/ColorPalette';
const AddNote = ({navigation, route}) => {
const [title, setTitle] = useState('');
const [detail, setDetail] = useState('');
const [color, setColor] = useState('#d4ff9b');
const [id, setId] = useState(0);
const [notes, setNotes] = useState([]);
// useEffect(()=>{
// console.log('NOTES: ',notes)
// updateDoc(docRef, {
// notes,
// })
// .then(() => {
// console.log('Updated');
// navigation.navigate('Notes');
// })
// },[notes]);
const docRef = doc(db, 'users', route.params.docId)
async function updateNotes() {
if (title === '' || detail === '') {
console.warn('Each input must have a value');
}
else {
setId((prev) => prev + 1);
setNotes(prev => [...prev, {title: title, details:detail, color:color}]);
}
}
const update = () => {
updateDoc(docRef, {
notes,
})
.then(() => {
console.log('UPDATED')
navigation.navigate('Notes');
})
}
return (
<View style={styles.noteContainer}>
<View style={styles.titleContainer}>
<TextInput style={styles.title} value={title} onChangeText={(text) => setTitle(text)} />
</View>
<View style={styles.detailsContainer}>
<TextInput style={styles.details} value={detail} onChangeText={(text) => setDetail(text)} multiline />
</View>
<View style={styles.bottomContainer}>
<View style={[styles.buttonContainer, {backgroundColor: '#00bfff'}]}>
<Pressable android_ripple={{color: '#d9d9d9'}} onPress={update}>
<FontAwesome style={styles.icon} name='send' size={40}/>
</Pressable>
</View>
<View style={styles.buttonContainer}>
<Pressable android_ripple={{color: '#d9d9d9'}} onPress={updateNotes}>
<Entypo style={styles.icon} name='save' size={40}/>
</Pressable>
</View>
</View>
</View>
)
}
I am currently dealing with this problem by setting states and updating them to the cloud with two different buttons.
4
Answers
use useEffect
I think you need to use
useEffect
for this like below:or you can use another temporary variable like this:
you might update your notes on some event or useEffect(by adding dependency array of title, detail.
There might be a delay in the update. you might try setting up a timer to give enough time to update the useState.
or You can try state variables as a dependencies