gpt4 book ai didi

reactjs - 使用 useEffect() Hook 和 Async/Await 从 Firebase/Firestore 获取数据

转载 作者:行者123 更新时间:2023-12-03 14:44:44 36 4
gpt4 key购买 nike

1. 我的意图:

使用 使用效果()从 props 中初始化组件的 state 变量的钩子(Hook),其数据是使用 从 firebase 中提取的mapStateToProps() .

2.问题:无法初始化组件的状态变量

  • 这个想法是 useEffect 只会在组件安装时运行一次。在这个初始化窗口中,我想将数据从 firebase 加载到这个组件的本地状态变量中。
  • running the example in this tutorial 时效果很好.在其中,他使用 axios() 获取 中的数据异步/等待 功能。有关他的代码,请参见下面的第 3 节。
  • 但是当我这样做时,尝试从与 Firestore 同步或初始化的 Prop 中获取数据时,我一直为空,无法从 result 中检索数据从我的 async/await 函数返回。
  • 我认为这是因为我对 async/await 缺乏了解。我无法创建有效的 异步/等待 从 Prop 中检索数据的函数。

  • 问题:

    我怀疑这就是问题所在。那么,写 的正确方法是什么?异步/等待 从与firebase同步的 Prop 中正确检索数据的函数?

    我的问题代码:
        import React, { useState, useEffect} from "react";
    import { connect } from "react-redux";
    import { firestoreConnect } from "react-redux-firebase";
    import { compose } from "redux";

    const app = props => {
    const { order } = props;
    const [data, setData] = useState({});

    useEffect(() => {
    const fetchData = async () => {
    const result = await (() => {
    return new Promise(resolve => {
    if (order) { resolve(order); }
    });
    })();
    setData(result);
    };
    fetchData();
    }, []);
    /** if I leave useEffect's second argument empty, which is intended to run only once at the beginning, then i'm getting null */

    ...

    const mapStateToProps = state => {
    const id = "DKA77MC2w3g0ACEy630g"; // docId for testing purpose.
    const orders = state.firestore.data.orders;
    const order = orders ? orders[id] : null;
    return {
    order: order
    };
    };

    export default compose(
    connect(mapStateToProps),
    firestoreConnect([{collection: "orders"}])
    )(app);

    我试过的:
  • 如果我添加 订购 进入第二个参数,然后它将正确地将数据加载到组件的状态变量中。但它会将 Prop 的数据重新加载到组件的状态变量中,并删除每个重新渲染周期中的任何更改。
  •  useEffect(() => {
    ...
    }, [order]);
  • mapStateToProps() 在初始组件安装后发生?因为这将解释为什么在初始效果中, Prop 总是空的。


  • 3. 我正在学习的教程:使用钩子(Hook)获取数据

    我能够使用 techniques from this tutorial 成功获取数据:
      const [data, setData] = useState({ hits: [] });
    useEffect(() => {
    const fetchData = async () => {
    const result = await axios(
    "https://hn.algolia.com/api/v1/search?query=redux"
    );
    setData(result.data);
    };
    fetchData();
    }, []);

    最佳答案

    听起来像 order可能是父级每次创建的对象。钩子(Hook)依赖检查精确匹配——previous === next -- 所以即使对象内部的值没有变化,如果对象本身发生变化,效果也会再次运行。
    发生这种情况的最常见方式是传递普通的对象字面量:

    const order = { id: 'foo', SKU: 'bar', cost: 19.95, quantity: 1 };
    return <App order={order} />;
    这将重新填充 order每次都使用新的对象文字。当您将一个对象散布到另一个对象中时,会发生更隐蔽的文字重新创建:
    const order = { ...oldOrder, quantity: 2 };
    这仍然会创建一个新对象。
    不要试图改变现有对象。 React 会开始对你做一些非常奇怪的事情。一旦你理解了钩子(Hook)依赖是如何工作的,变异对象会让你陷入困境。
    你有三个选择:
    使用原语作为依赖项
    如果您可以确定应该从服务器强制刷新的内容,请将其拉​​入其自己的变量中,并基于此设置您的依赖关系。仅当您只需要向服务器发送有限数量的字段时,这才有效。
    如果在您的示例中,您只需要订单的 id要调用电话,您可以将其提取到自己的变量中:
    const orderId = order.id;

    useEffect(() => {
    const fetchData = async () => {
    const response = await axios(`url-with-id?orderId=${orderId}`);
    setData(response.data);
    };
    fetchData();
    }, [orderID]);
    请注意,如果您尝试访问整个 order效果中的对象,即使你没有将它包含在依赖数组中,React 也会提示,这是有充分理由的。除非你能绝对保证它永远不会改变,除非 orderId也会发生变化,它可能会导致运行时错误,稍后会影响您。仅在效果中使用依赖数组中的内容。
    记住你的对象
    如果您的 order object 很简单,你可以根据它的内容来内存它。 useMemo接受一个依赖数组,同样的方式 useEffect确实如此,但不是在依赖项更改时运行效果, useMemo每当依赖项发生变化时返回一个新对象。
    只要没有任何依赖改变, useMemo返回相同的对象。这就是为什么它有效的关键。
    如果 order有几个简单的值,例如 id , SKU , price , 和 quantity ,您可以将对象文字创建更改为如下所示:
    const order = useMemo(
    () => ({
    id,
    SKU,
    price,
    quantity
    }),
    [id, SKU, price, quantity]
    );
    现在,只要 order 中没有数字或字符串改变,你每次渲染都会得到相同的对象。由于是同一个对象, useEffect(..., [order])只会运行一次。如果其中一个值发生变化,则新的 order将提供对象, useEffect的依赖数组被改变,并且为新的 order 运行效果.
    看看你为什么不断得到新的 order对象
    在您的情况下,看起来您正在获得 order来自 Redux 存储的对象。 Redux 仅在必要时才依赖其数据进行更改。每次 Redux 中的数据发生变化时,都会触发每个需要它的组件的变化。如果数据发生不必要的更改,这可能会导致您获取不断更新的对象。
    您需要查看是否有另一个组件将不必要的操作分派(dispatch)给 Redux,或者您的 reducer 是否在不需要时意外创建了所有新对象。 parent 是否在不检查是否需要更新的情况下进行更新?您是否有对数据存储进行大规模更新的异步操作(thunk 或 saga)?您是否在简单地将新数据写入旧数据之前检查传入数据和现有数据之间的增量?
    Redux 状态管理本身就是一个完整的主题。 Redux Toolkit 可能更容易使用比自己动手。它负责处理需要在商店中重新创建的内容,而无需您管理不变性问题。如果 FireBase 数据随意覆盖您的数据,Redux Toolkit 可以更轻松地确保仅更新调用之间更改的数据,而不是一直更改所有内容。

    关于reactjs - 使用 useEffect() Hook 和 Async/Await 从 Firebase/Firestore 获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58227421/

    36 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com