Files
rowy/src/hooks/useDoc.ts
2019-09-22 22:49:39 +10:00

67 lines
1.6 KiB
TypeScript

import { db } from "../firebase";
import { useEffect, useReducer } from "react";
export enum DocActions {
update,
delete,
}
const documentReducer = (prevState: any, newProps: any) => {
switch (newProps.action) {
case DocActions.update:
prevState.ref.update({ ...newProps.data });
return { ...prevState, doc: { ...prevState.doc, ...newProps.data } };
case DocActions.delete:
prevState.ref.delete();
return null;
default:
return { ...prevState, ...newProps };
}
};
const documentIntialState = {
path: null,
prevPath: null,
doc: null,
ref: null,
loading: true,
};
const useDoc = (intialOverrides: any) => {
const [documentState, documentDispatch] = useReducer(documentReducer, {
...documentIntialState,
...intialOverrides,
});
const setDocumentListner = () => {
documentDispatch({ prevPath: documentState.path });
const unsubscribe = db.doc(documentState.path).onSnapshot(snapshot => {
if (snapshot.exists) {
const data = snapshot.data();
const id = snapshot.id;
const doc = { ...data, id };
documentDispatch({
doc,
ref: snapshot.ref,
loading: false,
});
}
});
documentDispatch({ unsubscribe });
};
useEffect(() => {
const { path, prevPath, unsubscribe } = documentState;
if (path && path !== prevPath) {
if (unsubscribe) unsubscribe();
setDocumentListner();
}
}, [documentState]);
useEffect(
() => () => {
if (documentState.unsubscribe) documentState.unsubscribe();
},
[]
);
return [documentState, documentDispatch];
};
export default useDoc;