Delete doc on component unmount (React and Firebase)

Viewed 72

I have a react component that will create a new document on mounting

const CreateGame: React.FunctionComponent<ICreateGameProps> = (props) => {


    const gamesRef = useFirestore()
        .collection('Games')

    const [newGameId, setNewGameId] = useState('')

    useEffect(() => {
        const newGame: IGameDoc = {
            playerTurn: 'x',
            secondPlayerJoined: false,
            gameState: {
                rowOne: [null, null, null],
                rowTwo: [null, null, null],
                rowThree: [null, null, null]
            }
        }

        gamesRef.add(newGame)
            .then(docRef => setNewGameId(docRef.id))

        return () => {
            gamesRef.doc(newGameId).delete()
        }

    }, [])

however, as soon as the component unmounts again, I would like to delete that same document again, hence I have the cleanup function in my useEffect hook

return () => {
    gamesRef.doc(newGameId).delete()
}

This does not work however. Does anyone know why?

1 Answers

Issue

It doesn't work because it seems you close over the initial newGameId state which has a value of '' and isn't the docRef.id it's updated to.

Solution

Use an additional useRef hook to cache a copy of the newGameId state value and reference this in the useEffect hook's cleanup function.

const gameIdRef = useRef(); // <-- create a ref to store game id
const gamesRef = useFirestore().collection('Games');

const [newGameId, setNewGameId] = useState('');

useEffect(() => {
  const newGame: IGameDoc = {
    playerTurn: 'x',
    secondPlayerJoined: false,
    gameState: {
      rowOne: [null, null, null],
      rowTwo: [null, null, null],
      rowThree: [null, null, null]
    }
  }

  gamesRef
    .add(newGame)
    .then(docRef => {
      setNewGameId(docRef.id);
      gameIdRef.current = docRef.id; // <-- cache game id
    })

  return () => {
    gamesRef.doc(gameIdRef.current).delete(); // <-- access ref's current value
  };
}, []);
Related