Quiero asignar la ID en un complemento de Firebase antes de enviarlo.
const ref = firebase.firestore().collection('trips').doc(); const tripid = ref.id;Esto funciona bien, pero noto que cada vez que cambio o edito un campo antes de enviarlo, esta variable tripid cambia. Básicamente, tengo una función de carga que almacena el documento bajo su ID de usuario/tripid.
Si asigno la const de ref.id, ¿cómo evito que esto cambie en las ediciones de campo? Como si subieran un documento, entra en la identificación en ese momento, y luego, si editan otros campos antes de enviar, la identificación cambia y la referencia se pierde.
Suponiendo que la función de su componente se vea así:
function YourComponent({ props }) { const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const ref = firebase.firestore().collection('trips').doc(); const tripid = ref.id; return ( /* ... form ... */ ); }Cada vez que ese componente se vuelve a renderizar, la referencia generada cambiará.
Para evitar esto, debe introducir una función que genere su referencia solo una vez y la deje intacta cuando vuelva a dibujar su componente. Esto se puede hacer usando useMemo .
function YourComponent({ props }) { const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); // create `ref` once on the first render, don't recompute it even on redraws const ref = useMemo( () => firebase.firestore().collection('trips').doc(), [] // no dependencies, don't recompute ); const tripid = ref.id; return ( /* ... form ... */ ); } Sin embargo, en el futuro, useMemo no podrá usarse de esta manera (y lo advierte en su documentación , por lo que podemos crear el nuestro propio así:
// fork of useMemo, this can be elsewhere in your code so you can reuse it function usePersistentObject(init, deps) { const obj = useRef(null); const prevDeps = useRef(deps || []); if (obj.current === null || !(prevDeps.current.length === deps.length && prevDeps.current.every((v, i) => deps[i] === v))) { // rough shallow equals, could use a library // either first render or deps array values changed obj.current = init(); // compute prevDeps.current = deps; // save dependency state } return obj.current; } function YourComponent({ props }) { const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); // create `ref` once on the first render, don't recompute it even on redraws const ref = usePersistentObject( () => firebase.firestore().collection('trips').doc(), [] // no dependencies, don't recompute ); const tripid = ref.id; return ( /* ... form ... */ ); } Nota: ¡Si YourComponent está desmontado, la referencia cambiará!