I am wanting to assign the ID on a firebase add before submit.
const ref = firebase.firestore().collection('trips').doc();
const tripid = ref.id;
This works well, but I notice everytime I change or edit a field prior to submitting that this tripid variable changes. Basically I have an upload function that stores the document under their User ID / tripid.
If assigning the const of ref.id - how do I avoid this changing on field edits? As if they upload a document it goes into the ID at that time, and then if they edit other fields before submit the ID changes, and the reference is lost.
Assuming your component function looks something like this:
function YourComponent({ props }) {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const ref = firebase.firestore().collection('trips').doc();
const tripid = ref.id;
return ( /* ... form ... */ );
}
Every time that component rerenders, the generated ref will change.
To prevent this, you need to introduce a function that generates your reference just once and leaves it untouched when you redraw your component. This can be done using 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 ... */ );
}
However in the future useMemo won't be able to be used this way (and it warns as such in its documentation, so we can create our own like so:
// 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 ... */ );
}
Note: If YourComponent is unmounted the reference will change!