Search code examples
reactjsreact-nativereact-flatlist

How can I modify the A component that render in react to update?


I'm working on a React Native project and using the FlatList component to render a list of items. Each item has an Updated function that should update and display the elapsed time every 3 seconds.

React-Native

// Function to calculate and continuously update the elapsed time
const Updated = (item) => {
  setInterval(() => {
    // Extract the server timestamp from the item
    const ServerStamp = item.time;

    // Convert server timestamp to milliseconds
    const serverTimeInMilliseconds = ServerStamp.seconds * 1000 + ServerStamp.nanoseconds / 1e6;

    // Get the current time
    const currentTime = new Date();

    // Calculate the time passed since the server timestamp
    const timePassedInMilliseconds = currentTime.getTime() - serverTimeInMilliseconds;

    // Calculate hours
    const hours = Math.floor(timePassedInMilliseconds / (60 * 60 * 1000));

    // Calculate remaining milliseconds after hours
    const remainingMilliseconds = timePassedInMilliseconds % (60 * 60 * 1000);

    // Calculate minutes from remaining milliseconds
    const minutes = Math.floor(remainingMilliseconds / (60 * 1000));

    // Format the elapsed time as hours:minutes
    const msgTime = hours + ':' + minutes;

    // Log the formatted time to the console
    console.log(msgTime);

    // Return the formatted time (Note: this return statement is not used in your current code)
    return msgTime;
  }, 3000); // Update the elapsed time every 3 seconds
}

// renderItem method used in FlatList
const renderItem = ({ item }) => {
  // Find the corresponding surname for the item
  const surname = named.find((dataID) => dataID.id === item.id);

  // Check if surname is found
  if (surname) {
    return (
      <View style={{ padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc' }}>
        {/* Display the name */}
        <Text>Name: {surname.name}</Text>
        
        {/* Call Updated function to display and continuously update the elapsed time */}
        <Text>Minutes: {Updated(item)}</Text>
        
        {/* Placeholder for Location */}
        <Text>Location: ?</Text>
        
        {/* Display the status */}
        <Text>Status: {item.status}</Text>
        
        {/* SelectList component for changing status */}
        <SelectList
          placeholderTextColor="#ccc"
          search={true}
          setSelected={(val) => handleStatusChange(val, item.id)}
          data={statusOptions}
          save="value"
          color="white"
          placeholder={item.status}
        />
      </View>
    );
  }
};

// Main component JSX
return (
  <View>
    {/* FlatList component to render the list of items */}
    <FlatList
      data={person}
      renderItem={renderItem}
      keyExtractor={(item) => item.id}
    />
    
    {/* Button for logging the timestamp of the first item in the console */}
    <Button title='click' onPress={() => console.log(person[0].time)} />
  </View>
);

`

i want to update the

<Text>Minutes: {Updated(item)}</Text> every 1min

Solution

  • You need to use React.useState in order to change React-Native props and values.

    You can:

    A- Have an ItemComponent outside main function with useState and useEffect. The Updated wont need setIntervals.

    const Updated = () => {
      // do something with time and return custom time
      return Date.now();
    };
    
    const ItemComponent = ({ item }) => {
      const [itemTime, setItemTime] = React.useState(() => Updated(item));
    
      React.useEffect(() => {
        const interval = setInterval(() => {
          setItemTime(Updated(item));
        }, 3000);
        return () => clearInterval(interval);
      }, []);
    
      return (
        <View>
          <Text>{itemTime}</Text>
          {/* otherComponents */}
        </View>
      );
    };
    
    function App() {
      return (
        <View>
          <FlatList
            data={person}
            renderItem={({ item }) => <ItemComponent item={item} />}
            keyExtractor={(item) => item.id}
          />
        </View>
      );
    }
    

    B- Convert update function into a hook

    const useUpdateTime = (item) => {
      const Updated = () => {
        // do something with time and return custom time
        return Date.now();
      };
    
      const [itemTime, setItemTime] = React.useState(() => Updated(item));
    
      React.useEffect(() => {
        const interval = setInterval(() => {
          setItemTime(Updated(item));
        }, 3000);
        return () => clearInterval(interval);
      }, []);
    
      return itemTime;
    };
    
    const ItemComponent = ({ item }) => {
      const itemTime = useUpdateTime(item);
      return (
        <View>
          <Text>{itemTime}</Text>
          {/* otherComponents */}
        </View>
      );
    };
    
    function App() {
      return (
        <View>
          <FlatList
            data={person}
            renderItem={({ item }) => <ItemComponent item={item} />}
            keyExtractor={(item) => item.id}
          />
        </View>
      );
    }
    

    There are other options like having useState and useEffect in main function and changing all items together.