Home > Back-end >  Why is my react mapped array flashing and then disappearing?
Why is my react mapped array flashing and then disappearing?

Time:08-15

i am retrieving an array of objects containing my firestore storage file information using the function below

export const listFiles = async () => {
  const listRef = ref(storage, "/");
  const files: any = [];
  await listAll(listRef)
    .then((res) => {
      res.items.forEach((itemRef) => {
        getMetadata(itemRef).then((metadata) => {
          files.push({
            name: metadata.fullPath,
            created: metadata.timeCreated,
          });
        });
      });
    })
    .catch((error) => console.error(error));

  return files;
};

in my react front end i call the function the firestore function and set a files state variable equal to the result of the function using code below

const [files, setFiles] = useState<any | any>(null);
...
  useEffect(() => {
    const fetch = async () => {
      const filesList: any = await listFiles();
      setFiles(filesList)
    };
    fetch();
  }, []);

i then map over the returned array in the code below (using chakra ui components btw)

<Box textAlign="center">
        {files && (
          <>
            <Text fontSize="3xl">Uploaded Files</Text>
            {files.map((file: any) => {
              return (
                <Box
                  display="flex"
                  alignItems="center"
                  key={file.name}
                  bg="gray.200"
                  m={5}
                  borderRadius="lg"
                  p="2"
                  justifyContent="space-between"
                >
                  <Box textAlign="initial">
                    <Text>{file.name}</Text>
                    <Text>{file.created}</Text>
                  </Box>
                  <Button>
                    <BsCloudDownload />
                  </Button>
                </Box>
              );
            })}
          </>
        )}
      </Box>

any ideas why my content appears for a second and then disappears? i've seen others with similar issues in other posts, but have not been able to fix with any solutions i've seen. probably a dumb mistake somewhere, let me know

thanks again

EDIT: i removed try catch from my firestore query.. let me know if this looks right?

export const listTheFiles = async () => {
  const listRef = ref(storage);
  const files: any = [];
  const response = await listAll(listRef);
  response.items.forEach(async (itemRef) => {
    const metadata = await getMetadata(itemRef);
    files.push({ name: metadata.fullPath, created: metadata.timeCreated });
  });
  console.log(files);
  return files;
};

CodePudding user response:

The issue is due to promises inside listFiles function are not handled correctly, so files were returned as empty array, even if this array will be populated in future - react will not detect that and will not rerender the component. Also, it is a bad practice to mix async with .then.catch promises api.

Fixed method:

export const listFiles = async () => {
  const listRef = ref(storage, "/");
  const listAllResult = await listAll(listRef);

  const promises = listAllResult.items.map(async (itemRef) => {
    const metadata = await getMetadata(itemRef);
    return {
      name: metadata.fullPath,
      created: metadata.timeCreated
    };
  });

  return Promise.all(promises);
};

Sorry, i cant test it at this moment but if you encounter any issues after that - feel free to comment me and i'll update the answer.

CodePudding user response:

you can try writing the component like this and see if the issue persists :

<Box textAlign="center">
    <Text fontSize="3xl">Uploaded Files</Text>
    {
        files?.map((file) => {
            return (
                <Box
                    display="flex"
                    alignItems="center"
                    key={file.name}
                    bg="gray.200"
                    m={5}
                    borderRadius="lg"
                    p="2"
                    justifyContent="space-between"
                >
                    <Box textAlign="initial">
                        <Text>{file.name}</Text>
                        <Text>{file.created}</Text>
                    </Box>
                    <Button>
                        <BsCloudDownload />
                    </Button>
                </Box>
            );
        })
    }
</Box>

it would also be helpful to know if you get any type of error in your console.

  • Related