0

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.

  • 1
    You need to use useEffect if you need functions to trigger on load – ShubhankarKG Mar 04 '23 at 11:18
  • When I put my set state functions in useEffect, notes array fills with every iteration that I write as title and details. – bitterkofte Mar 04 '23 at 11:37
  • Does this answer your question? [React setState not updating state](https://stackoverflow.com/questions/41446560/react-setstate-not-updating-state) – Abe Mar 04 '23 at 18:43

4 Answers4

1

use useEffect

useEffect(()=>{
    updateDoc(docRef, {
      notes,
    })
    .then(() => {
      console.log('UPDATED')
      navigation.navigate('Notes');
    })
},[])
phuocantd
  • 452
  • 4
  • 12
1

I think you need to use useEffect for this like below:

useEffect(() => {
   updateDoc(docRef, {
        notes,
      })
      .then(() => {
        console.log('UPDATED')
        navigation.navigate('Notes');
      })
}, [notes])

or you can use another temporary variable like this:

function updateNotes() {
    if (title === '' || detail === '') {
      console.warn('Each input must have a value');
    }
    else {
      const tempNotes = [...notes, {title: title, details:detail, color:color}]
      setNotes(tempNotes);
      console.log(tempNotes);
      updateDoc(docRef, {
        tempNotes,
      })
      .then(() => {
        console.log('UPDATED')
        navigation.navigate('Notes');
      })
    }
  }
Yakupguly Malikov
  • 584
  • 1
  • 1
  • 12
1

There might be a delay in the update. you might try setting up a timer to give enough time to update the useState.

function updateNotes() {
    if (title === '' || detail === '') {
      console.warn('Each input must have a value');
    } else {
      setId((prev) => prev + 1);
      // Delay the state update by 10 milliseconds
      setTimeout(() => {
        setNotes(prev => [...prev, {title: title, details: detail, color: color}]);
      }, 10);
    }
  }

or You can try state variables as a dependencies

useEffect(() => {
    setId((prev) => prev + 1);
    setNotes(prev => [...prev, {title: title, details: detail, color: color}]);
  }, [title, detail]);
Tula Magar
  • 135
  • 10
0

you might update your notes on some event or useEffect(by adding dependency array of title, detail.

Asma
  • 103
  • 5