【问题标题】:Firebase/React: Get Document ID before creationFirebase/React:在创建之前获取文档 ID
【发布时间】:2021-10-25 07:24:27
【问题描述】:

我想在提交之前在 firebase 添加上分配 ID。

const ref = firebase.firestore().collection('trips').doc();
const tripid = ref.id;

这很好用,但我注意到每次在提交之前更改或编辑字段时,此三元组变量都会更改。基本上我有一个上传功能,将文档存储在他们的用户 ID/tripid 下。

如果分配 ref.id 的 const - 如何避免在字段编辑时发生这种变化?就好像他们上传一个文档一样,它会进入当时的 ID,然后如果他们在提交 ID 更改之前编辑其他字段,那么引用就会丢失。

【问题讨论】:

    标签: javascript reactjs firebase google-cloud-firestore


    【解决方案1】:

    假设你的组件函数看起来像这样:

    function YourComponent({ props }) {
      const [firstName, setFirstName] = useState("");  
      const [lastName, setLastName] = useState("");
    
      const ref = firebase.firestore().collection('trips').doc();
      const tripid = ref.id;
    
      return ( /* ... form ... */ );
    }
    

    每次该组件重新渲染时,生成的 ref 都会发生变化。

    为防止这种情况发生,您需要引入一个函数,该函数只生成一次引用并在重绘组件时保持不变。这可以使用useMemo 来完成。

    function YourComponent({ props }) {
      const [firstName, setFirstName] = useState("");  
      const [lastName, setLastName] = useState("");
      
      // create `ref` once on the first render, don't recompute it even on redraws
      const ref = useMemo(
        () => firebase.firestore().collection('trips').doc(),
        [] // no dependencies, don't recompute
      );
    
      const tripid = ref.id;
    
      return ( /* ... form ... */ );
    }
    

    但是,将来useMemo 将无法以这种方式使用(它会在its documentation 中发出警告,因此我们可以像这样创建自己的:

    // fork of useMemo, this can be elsewhere in your code so you can reuse it
    function usePersistentObject(init, deps) {
      const obj = useRef(null);
      const prevDeps = useRef(deps || []);
    
      if (obj.current === null || !(prevDeps.current.length === deps.length && prevDeps.current.every((v, i) => deps[i] === v))) { // rough shallow equals, could use a library
        // either first render or deps array values changed
        obj.current = init();    // compute
        prevDeps.current = deps; // save dependency state
      }
    
      return obj.current;
    }
    
    function YourComponent({ props }) {
      const [firstName, setFirstName] = useState("");  
      const [lastName, setLastName] = useState("");
      
      // create `ref` once on the first render, don't recompute it even on redraws
      const ref = usePersistentObject(
        () => firebase.firestore().collection('trips').doc(),
        [] // no dependencies, don't recompute
      );
    
      const tripid = ref.id;
    
      return ( /* ... form ... */ );
    }
    

    注意:如果YourComponent 被卸载,引用将会改变!

    【讨论】:

    • 谢谢。如果我在tripid 上尝试console.log - 我得到一个未定义的错误?
    • @PaulVI 抱歉,我的钩子一直都搞混了。已更新。
    • 感谢@samthecodingman - 我实现了这个解决方案,重新渲染时 ID 似乎没有变化 - 但是当我提交表单时,ID 不同
    • 只是重温一下,我注意到提交 ID 后保持不变 - 一旦他们提交表单,我如何生成新 ID?或者如何刷新 ID
    • @PaulVI 您可以在某处添加“lastSubmittedTime”变量(或其他在提交后会更改的变量),将其作为属性传递给YourComponent,然后将其添加到useMemo 的依赖项中/usePersistentObject 调用(即[][props.lastSubmittedTime])。只要变量不改变,就不会在组件的生命周期内计算新的 ID。
    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    相关资源
    最近更新 更多