javascript - 从复杂的反应组件中拆分逻辑
问题描述
介绍
我真的不知道从大屏幕上拆分逻辑(获取或其他类型的逻辑)。我的意思是,在一个组件中拥有比 JSX 标签更多的逻辑似乎真的很不专业,而且我确信我不是世界上唯一遇到这种问题的开发人员,所以我决定在这里提问,以获得一个好的答案.
在我的用例中,我使用 Firebase CLI 从我的数据库中获取数据
/users (collection)
userId (document)
-name
-avatar
-age
/bosses (collection)
userId (document)
-other info
/cellebrety (collection)
userId (document)
-other info
/filmmakers (collection)
userId (document)
-other info
/books (collection)
userId (document)
userBooks (collection)
bookId (document)
-book info
...
以及用于身份验证、将图像存储到我的存储等。
因此,我决定创建一个“Firebase”类,如下所示:
export default function Firebase() {
if (!firebase.apps.length) {
// Initialize App
firebase.initializeApp(Constants.manifest.web.config.firebase);
// Initialize firebase services
this.auth = firebase.auth();
this.firestore = firebase.firestore();
this.functions = firebase.functions();
this.storage = firebase.storage();
}
}
Firebase.prototype.enableAuthPersistence = function () {
...
};
Firebase.prototype.signInWithEmailAndPassword = function (email, password) {
...
};
Firebase.prototype.signInWithUsernameAndPassword = function (username, password) {
...
};
Firebase.prototype.uploadImageToStorage = async function (
imageUri,
storageFolder
) {
...
};
Firebase.prototype.getCurrentUser = function () {
...
};
...
问题
为了避免将我的所有数据库查询实现为此类的函数,以防止该类成为“上帝”类,我决定将所有查询逻辑放在我呈现内容的屏幕中。但是,一切都变得非常重复,就像在我的应用程序中一样,当它安装、刷新等时,我必须按照类似的语法和相同的模式查询每个屏幕上的内容:
...
const getMoreFilmmakers = () => {
// Do nothing if currently fetching
if (isFetching.current) return;
// Start mutual exclusion
isFetching.current = true;
// Perform query
const query = firebase.firestore.collection("filmmakers").where(...);
const snapshot = await query.limit(10).get();
...
// Prepare (some kind of parsing) the fetched data
const filmmakers = prepareFilmmakers(retrievedData);
// Update states
setFilmakers(filmmakers)
setIsLoading(false);
// Stop mutual exclusion
isFetching.current = false;
}
const prepareFilmmakers = (data) => {
// Preparing data to be rendered...
}
useEffect(() => {
getMoreFilmmakers();
}, []);
...
在每个屏幕上都有所有这些东西对我来说似乎是重复的,因为在大多数情况下,唯一改变的是执行查询的集合。
例如,在其他屏幕中,程序员可以这样做:
...
const getMoreBooks = (userId) => {
// Do nothing if currently fetching
if (isFetching.current) return;
// Start mutual exclusion
isFetching.current = true;
// Perform query (get the books of a user ordered by cost)
const query = firebase.firestore.collection("books").doc(userId).collection("userBooks").orderBy("price");
const snapshot = await query.limit(10).get();
...
// Prepare (some kind of parsing) the fetched data
const books = prepareBooks(retrievedData);
// Update states
setBooks(books)
setIsLoading(false);
// Stop mutual exclusion
isFetching.current = false;
}
const prepareBooks = (data) => {
// Preparing data to be rendered...
}
useEffect(() => {
getMoreBooks();
}, []);
...
此时,如您所见,代码变得重复,我们只是在所有屏幕上获取、准备(解析)和渲染、复制代码行,仅用于更改集合或查询。
另外,如果在不久的将来我决定在一个屏幕上呈现多个水平列表(执行不同类型的查询)呢?
- list for users
- list for bosses
- list for cellebrity
- list for filmmakers
...
在这种情况下,我将真正拥有一个巨大的屏幕,它可以完美地达到 750 行代码,而且大部分都非常相似......
我曾考虑将所有逻辑移至子组件……但代码仍会重复,因为它只会减少屏幕的行数,将它们移至子组件。
有没有一种简单的方法来处理这个问题并有一种通用的方法来执行查询?任何提示或建议?将逻辑移动到“逻辑”HOC 或挂钩是否正确?谢谢你。
解决方案
推荐阅读
- javascript - 如果有多个相同类类型的按钮,Puppeteer 如何指定一个按钮?
- python - Python SQL - 将值插入列表中的可识别列
- java - Major GC 性能下降
- java - 按钮颜色不变...(Android)
- javascript - 想将一系列字符串和数字转换成我已经声明过的变量
- python - 使用 Python,我如何将逻辑(或类似的 s 形函数)拟合到 3 个点?
- arrays - 如何找到一个元素并删除所有以下元素?
- cmake - 如何检查在 CMake 中是否已经调用了 include(CPack)?
- next.js - 如何在使用 ESLINT 的 fetch 命令中要求绝对 URL
- c# - 使用 ManagementObjectSearcher 时出现 SEHException