首页 > 解决方案 > 将逻辑以 SRP 方式处理 Redux sagas 与 Firestore 的最佳位置,

问题描述

了解有关Redux Sagas和 Reducer 模式的更多信息,并想询问如何以合理的方式抽象我的工作流程。

我有一个非常简单的“标签”文档的后端 Firestore 集合。
Tag 是一个 json 对象,例如 {"name": "Bmw"}。

当标签被更改、修改或删除时,我使用Saga 频道来监听这样的更改。

这是代码简单设置:

function* tagsListenerSaga() {
    const firebase = yield getContext('firebase');
    const ref = firebase.db.collection(FIRESTORE.GLOBAL_TAGS).orderBy(FIRESTORE.NAME);
    const channel = yield call(metaEventListener, ref);
    try {
        while (true) {
            const querySnapshot = yield take(channel);
            const addedTags = [];
            const modifiedTags = [];
            const deletedTags = [];

            querySnapshot.docChanges().forEach(doc => {
                if (doc.type === 'added') {
                    console.log('added : ', doc.doc.data());
                    addedTags.push({
                        ...doc.doc.data(),
                        id: doc.doc.id,
                    });
                }
                if (doc.type === 'modified') {
                    console.log('modified : ', doc.doc.data());
                    modifiedTags.push({
                        ...doc.doc.data(),
                        id: doc.doc.id,
                    });
                }
                if (doc.type === 'removed') {
                    console.log('removed : ', doc.doc.data());
                    deletedTags.push({
                        ...doc.doc.data(),
                        id: doc.doc.id,
                    });
                }
            });
            if (addedTags.length) {
                yield put(setTagsAdded(addedTags));
            }
            if (modifiedTags.length) {
                // yield put(setTagsModified(modifiedTags));
            }
            if (deletedTags.length) {
                // yield put(setTagsDeleted(deletedTags));
            }
        }
    } catch (error) {
        console.log(error);
    } finally {
        if (yield cancelled()) {
            console.log('error');
            channel.close();
        }
    }
}

const metaEventListener = ref => {
    const channel = eventChannel(emitter => {
        const unsubscribe = ref.onSnapshot(doc => {
            emitter(doc);
        });
        return unsubscribe;
    });
    return channel;
};

export default function* watchTagsMetaRequests() {
    yield takeLatest(globalActionTypes.START_LISTEN_TAGS, tagsListenerSaga);
}

正如您在 Saga中看到的那样,我响应 FirebasequerySnapshot并调用保存.yield put(setTagsAdded(addedTags));reduceraddedTags

在 Saga 中,我拥有所有三个:

    if (addedTags.length) {
        yield put(setTagsAdded(addedTags));
    }
    if (modifiedTags.length) {
        // yield put(setTagsModified(modifiedTags));
    }
    if (deletedTags.length) {
        // yield put(setTagsDeleted(deletedTags));
    }

为了处理将数据委托给reducer,我必须在某处将此tag更改添加到reducer状态。通过地图发送querySnapshotreducer内部reducer搜索tags并添加/删除/更新tags或,

应该/可以 Sagaselectreducer需要这样做,然后 Sagayield put..用更新的tags地图来做。这里的事务状态和原子性会发生什么?

我想以最好的方式遵守单一职责原则 (SRP),以了解未来最佳调制的
利弊吗?

标签: reactjsreduxgoogle-cloud-firestoreredux-sagareducers

解决方案


推荐阅读