Search code examples
react-nativeapicomponentsrefresh

React Native - JSON reponse is not updating when doing the function again


I have a list of names rendered out in a flatList, this list takes me to a detail page with the ID of the user written out. If i go back with the menu to the list again and choose a different name the same name appears all the time until i refresh the app and do it again, then the first name chosen will continue to be there. The ID updates all the time, but not the "data.Name" in this case. How can i make it update itself so the name also changes?

App.js

function PlayersScreen( { navigation } ) {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);

  useEffect(() => {
  fetch('http://***.***.***.***/people',
   { credentials: "same-origin",
   headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json'
   },
  },
  )
    .then((response) => response.json())
    .then((json) => setData(json))
    .catch((error) => console.error(error))
    .finally(() => setLoading(false));
}, []);

  return (

         <FlatList
            data={data}
            keyExtractor={item => item.Name}
            renderItem={({ item }) => (
            <Text onPress={() => {navigation.navigate('DetailsScreen', {itemId: item._id})}}>{item.Name}</Text>
            )}
          />
  );
}

function DetailsScreen({ route, navigation }) {
  const { itemId } = route.params;
  console.log('DetailsScreen', itemId);
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  useEffect(() => {
  const apiurl = 'http://***.***.***.***:3000/people/' + itemId;
  fetch(apiurl)
  .then((response) => response.json())
  .then((responseJson) => {
    console.log(data);
   setData(responseJson)})
  .catch((error) => console.error(error))
  .finally(() => setLoading(false));
 
}, []);
     return (
    <View>
      <Text>Details Screen</Text>

      **<Text>itemId: {itemId}</Text>** <- THIS DOES CHANGE
      **<Text>{data.Name}</Text>** <- THIS DOES NOT CHANGE

      <Button title="Go back to List" onPress={() => navigation.navigate('people')} />
  );
}

Solution

  • I solved it. The problem was that on the detail screen, the useEffect did not re-render more then once because app.js did not re-render. The solution was simply as follows (Taken from ReactJS docs)

    useEffect(() => {
      document.title = `You clicked ${count} times`;
    }, [count]); // Only re-run the effect if count changes
    

    So my final code in the detail section ended up looking like this

    function DetailsScreen({ route, navigation }) {
      const { itemId } = route.params;
      console.log('DetailsScreen', itemId);
      /* 2. Get the param */
      const [isLoading, setLoading] = useState(true);
      const [data, setData] = useState([]);
      useEffect(() => {
      const apiurl = 'http://***.***.***.***:3000/************/' + itemId;
      console.log(apiurl)
      fetch(apiurl)
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
    }, [itemId]);
    

    itemId was added in the end brackets, so if it changes it's re-rendering.