skip to Main Content

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


  1. use useEffect

    useEffect(()=>{
        updateDoc(docRef, {
          notes,
        })
        .then(() => {
          console.log('UPDATED')
          navigation.navigate('Notes');
        })
    },[])
    
    Login or Signup to reply.
  2. 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');
          })
        }
      }
    
    Login or Signup to reply.
  3. you might update your notes on some event or useEffect(by adding dependency array of title, detail.

    Login or Signup to reply.
  4. 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]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search