Reactjs 我是否应该构建本地数据层/应用程序状态以维护React Native/Firestore应用程序中的状态?

Reactjs 我是否应该构建本地数据层/应用程序状态以维护React Native/Firestore应用程序中的状态?,reactjs,react-native,google-cloud-firestore,expo,react-native-firebase,Reactjs,React Native,Google Cloud Firestore,Expo,React Native Firebase,Firestore的一个主要卖点是能够将其用作在线/离线真相来源。我现在正以这种方式使用它:直接在一个操作上更新Firestore文档,然后监听Firestore DB的更改并将其映射回本地状态。但是,依赖于此并映射回本地状态不足以实现快速更新(即使文档大小很小,也可以点击、切换)。例如,切换将随着RN切换在点击时的移动而“抖动”,并且本地状态直到已经返回才被更新。Android上的情况似乎更糟,问题并不仅仅局限于基本的切换 文档大小或查询结果大小是否对延迟补偿有较大影响?我们的文档大小现在非常

Firestore的一个主要卖点是能够将其用作在线/离线真相来源。我现在正以这种方式使用它:直接在一个操作上更新Firestore文档,然后监听Firestore DB的更改并将其映射回本地状态。但是,依赖于此并映射回本地状态不足以实现快速更新(即使文档大小很小,也可以点击、切换)。例如,切换将随着RN切换在点击时的移动而“抖动”,并且本地状态直到已经返回才被更新。Android上的情况似乎更糟,问题并不仅仅局限于基本的切换

  • 文档大小或查询结果大小是否对延迟补偿有较大影响?我们的文档大小现在非常小,最坏的情况是1000个查询结果集。我们可以将文档放大1000倍(100kb),查询结果集的大小为1更新:此处的测试不一致,延迟补偿在这两种情况下都不理想
  • 以下哪些因素可能会影响延迟补偿

    • 使用带有自定义索引的查询。注意:我们目前没有从缓存中读取数据,我们使用的是JSSDK
    • 多次写入。对同一文档多次写入是否会使情况变得更糟(4次快速写入与2次快速写入)更新:不清楚这会造成很大的差异
    • 使用本机vs.JS模块。我们目前正在使用Firestore Web SDK和Expo应用程序更新:通过React native Firestore切换到本机模块没有明显的性能改进
  • 人们是否经常使用React Native/Firestore应用程序构建本地数据填充层/本地应用程序状态,以帮助提高本地性能速度?有没有关于这方面的建议图书馆

  • 加载应用程序时,装载侦听器,并将结果导出到上下文中,以便通过应用程序使用

    const [user, setUser] = useState();
    
    firebase.firestore().collection(`users/${user.uid}`).onSnapshot(qs => setUser(oldState => {
        const newState = {};
        qs.docChanges().forEach(change => {
          if (change.type === "added" || change.type === "modified") {
            newState[change.doc.id] = {
              docid: change.doc.id,
              ...change.doc.data(),
            };
          } else if (change.type === "removed") {
            delete oldState[change.doc.id];
          }
        });
    
        return {
          ...oldState,
          ...newState,
        };
      }))
    
    切换通知的示例组件和函数:(开关抖动)

    const-toggleNotifications=(用户,值)=>{
    firebase.firestore().doc(`users/${user.uid}`)。更新({
    WantNotification:值,
    });
    };
    常量TestComponent=()=>{
    //从上下文获取,在应用程序加载时装入的侦听器中设置
    const{user}=useUserContext();
    返回(
    toggleNotifications(用户,值)}
    />
    );
    };
    
    这不是答案,只是一条长长的评论:)

    @例如,learningAngular,在
    toggleNotifications
    中,只需调用一个,而不必担心将任何逻辑放入react组件中

    相反,Redux模式提供了执行某些逻辑的空间,在这种情况下,因为用户的最后一刻决定是事实的来源,所以分派函数在开始更新firestore之前总是设置一个本地
    tempState
    updateingstatus
    ,然后在firestore承诺解决或拒绝后,向reducer发送一个操作,以重置
    更新状态
    。然后a将检查
    updatestatus
    是否为true,以仅依赖于本地
    tempState
    否则依赖于存储状态。最后,react组件使用选择器结果作为当前有效状态


    我不回答这个问题,因为我没有那么多经验。我也很好奇是否有一个好的解决方案,但这就是我目前认为的解决方案。

    我用具体的知识更新了答案,但经过大量测试,我迄今为止最大的一般知识是

    • 即使使用相同的数据和环境,延迟补偿也可能非常不一致。正如其他问题中提到的,听众可以花时间“热身”。这里很难有一个标准的度量标准
    • 文档大小不会影响延迟补偿。到目前为止,其他一切都没有定论

    我建议使用来处理与firebase和firestore的异步通信。@Makan谢谢!监听器的自动绑定/解除绑定以及将集合映射到本地状态很好,但不确定它是否直接回答了这个问题。我认为react redux firebase提供的状态仍然依赖于更新firestore DB以接收更新。我的理解错了吗?你是对的,redux firestore也从firestore接收更新,但我想说的是利用redux提供的模式来保持状态几乎同步更新。在这种模式中,更新firestore将通过异步调度操作进行,最终更新状态。但是,它让我们有机会在调度操作之前更新本地状态,因此react组件可以依赖始终与firestore同步的本地状态。
    const toggleNotifications = (user, value) => {
      firebase.firestore().doc(`users/${user.uid}`).update({
        wantNotifications: value,
      });
    };
    
    const TestComponent = () => {
      //gets from context, set in listener mounted on app load
      const { user } = useUserContext();
      return (
        <Switch
          value={user.wantNotifications}
          onValueChange={value => toggleNotifications(user, value)}
        />
      );
    };