I'm currently working on a project with React and Firebase and at the moment my logic to write new data to Firestore is directly in my components. I'm now also integrating Redux, for this I am using react-redux-firebase. My question is now, where is the best place to put this logic, because it makes my component quiet bloated.
In the documentation of react-redux-firebase, they've also put it directly in the component, but their logic is quit simple, mine is a little bit more complex, like this handleSubmit:
const handleSubmit = async (e) => {
e.preventDefault();
setDisabled(true); //disable button to prevent multiple sbumits
setLoading(true);
try {
const docRef = await firestore.collection("goodies").add(newGoodieData); // create new event
await firestore.collection("goodies").doc(docRef.id).update({
// add eventId to event doc
id: docRef.id,
});
if (image) {
const imageName = docRef.id + "." + image.name.split(".").pop(); //create image name with eventID and file extions
const imageRef = storage.ref().child("goodie_images/").child(imageName); //create imageRef
const imageSnapshot = await imageRef.put(image); //upload image to storage
const downloadUrl = await imageSnapshot.ref.getDownloadURL(); //get image download-url
const imagePath = imageRef.fullPath; // get image storage path
await firestore.collection("goodies").doc(docRef.id).update({
//update event with imageUrl and imagePath
image: downloadUrl,
imagePath: imagePath,
});
}
setDisabled(false);
setLoading(false);
dispatch(showSuccessToast(`Created new goodie "${newGoodieData.name}"!`));
history.push("/goodies");
} catch (error) {
dispatch(showErrorToast("Ops, an error occurred!"));
console.error(error.message);
}
};
This is entirely my idiosyncrasy, but I use a structure like the below. In general, component and page (i.e react component) names are initial-capital:
BLOCKS
These are my application-specific components, and some larger application-specific functions.
COMPONENTS
These are "generalized" components - i.e could be released as modules, or are customized from external modules. These are NOT application-specific. Similar structure to "blocks"
CSS
As the name says...
NAVIGATION
Headers, Footers, navigation menus. Also navigation helper functions (such as wrapping links to pages, etc)
PAGES
All my react pages and sub-pages, to whatever depth are needed. Everything below pages is specific to the application
And where your question is more directly addressed:
SERVICES
Not yet much different than the tutorials. But this is what I have in my slices - which more-or-less-ish correspond to redux state slices:
SLICES
IMPORTANT NOTE: most Redux tutorials show the Redux slices having the same branching structure as the React components. In general THIS IS NOT AT ALL THE CASE, and I have yet to find a case where it is even helpful. The tree-like structure of your data is not necessarily at all like the tree-like structure of your pages and react components - divide your Redux store the way the data wants you to, not the way the user-facing React wants you to. Even more to the point for this forum: let the FIRESTORE structure of your data guide you.
In use:
...for example, imports and then exports all the public/exported symbols from
actions,reducerandbusiness....
reduceruses store.injectReducer to add itself to the Redux store, using symbols and constants defined in...
actions, which also creates the specific Redux actions and helper boiler plate (actions, selectors, etc).To help separate responsibility:
...
businesssub-directory holds the BUSINESS logic you mentioned - any logic that a React component might need to call that is NOT specifically local to the display & state aspects of the React modules. This is ALSO where I define any access to firestore, or any other external service or fetches - the React components should NOT care how this is done.To make accessing all of these various exports more convenient, I use
...which imports and then exports all the public/exported symbols from all the slices. Makes it easier to import into various React comopnents without worrying about changes to the underlying structure of
slicesAs I said, COMPLETELY my idiosyncrasy, but it helps to separate out responsibility.