skip to Main Content

I have a Host.js file which has a track list which is updated as defined by the setTrackListener() function. My issue is that everytime the function is called, the trackList isn’t actually updated. Here is an example print out:

Change detected in setTrackListener
 LOG  Track Name: TEST
 LOG  Current trackList:
 LOG  NewArray: TEST
 LOG  trackList after set:

Here is my code:

let authToken = "";
let roomID = "";

export default function Host({ navigation }) {
  if (roomID == "") {
    roomID = createRoom();
  }
  const [trackList, setTrackList] = useState([]);

  if (authToken == "") {
    getAuthAccessToken().then((t) => (authToken = t));
  }

  useEffect(() => {
    setTrackListener(roomID, (t) => {
      if (t != null) {
        console.log("Track Name: " + t.name);
        console.log("Current trackList: " + trackList);
        const newArray = [...trackList];
        newArray.push(t.name);
        console.log("NewArray: " + newArray);
        setTrackList(newArray);
        console.log("trackList after set: " + trackList);
      }
    });
 
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Hosting {roomID}</Text>
      <FlatList
        data={trackList}
        renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  title: {
    color: "#590",
    fontSize: 32,
  },
});

setTrackListener is defined in a seperate file, where I listen to changes on a specific Google Firebase Database. Here is that code:

let setTrackListener = (id, onChange) => {
  let tracksRef = ref(database, `rooms/${id}/tracks`);
  onChildAdded(tracksRef, (snapshot) => {
    const data = snapshot.val();
    console.log("Change detected in setTrackListener");
    onChange(data);
  });
};

If I instead update the trackList with button like the following, it does update:

<Button
  title={"Test"}
  onPress={() => {
  const newArray = [...trackList, "TEST"];
  setTrackList(newArray);
  console.log(trackList);
}}
></Button>

2

Answers


  1. To observe the updated state value, you can make use of the useEffect hook with a dependency on the trackList state.

    By adding [trackList] as the dependency array in the useEffect hook, the callback function will be called whenever the trackList state changes.

    useEffect(() => {
      setTrackListener(roomID, (t) => {
        if (t != null) {
          console.log("Track Name: " + t.name);
          console.log("Current trackList: " + trackList);
          const newArray = [...trackList, t.name];
          console.log("NewArray: " + newArray);
          setTrackList(newArray);
        }
      });
    }, [trackList]);
    Login or Signup to reply.
  2. The useEffect with [] will only run once. You need to add the changing dependencies e.g. [t]. t, t.name, or any props that their changes should trigger the setTrackListener.

    Also

    console.log("trackList after set: " + trackList)
    

    next to

    setTrackList(newArray) 
    

    would not show the latest state of the trackList.

    Try below as a seperate useEffect:

      useEffect(() => {
        console.log("Current trackList: " + trackList);
      }, [trackList]);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search