【问题标题】:How to handle async firebase calls with hooks如何使用钩子处理异步 Firebase 调用
【发布时间】:2019-11-15 13:41:42
【问题描述】:

我想创建一个挂钩来将数据添加到 Firestore 数据库。我不确定我是否误解了钩子的工作方式或 Firestore 的工作方式,我对这两者都是新手。

警告: 无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

Firebase API

  createTeam = newTeam => {
    return this.db.collection("teams").add({
      ...newTeam
    });
  };

钩子

export default function useFetch(action) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  async function performAction(body) {
    try {
      setLoading(true);
      setData(null);
      setError(null);
      const data = await action(body);
      setData(data);
    } catch (e) {
      setError(e);
    } finally {
      setLoading(false);
    }
  }

  return [{ loading, data, error }, performAction];
}

组件

  const [state, runFetch] = useFetch(db.createTeam);
  const { values, handleChange, isDirty, handleSubmit } = useForm({
    initialValues: {
      name: "",
      location: ""
    },
    onSubmit({ values }) {
      runFetch(values);
    },
    validate(e) {
      return e;
    }
  });

state.data 永远不会设置为预期的响应,但是,在 fetch 挂钩中等待之后的日志记录表明我正在接收响应。我应该在 useEffect 中这样做吗?通过 hooks/firebase 完成此任务的适当方法是什么?

【问题讨论】:

    标签: reactjs firebase firebase-realtime-database async-await react-hooks


    【解决方案1】:

    看看这是否适合你。

    这对于自定义钩子来说是个好主意。

    CodeSandbox 上的工作示例:

    https://codesandbox.io/s/clever-joliot-ukr1t

    index.js

    import React, { useState } from "react";
    import ReactDOM from "react-dom";
    
    import "./styles.css";
    
    function App() {
      const [state, runFetch] = useFetch(mockAPICall);
    
      function mockAPICall() {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve("Some data from DB!");
          }, 1000);
        });
      }
    
      return (
        <React.Fragment>
          <div>Loading: {state.loading ? "True" : "False"}</div>
          <div>Data: {state.data}</div>
          <button onClick={() => runFetch(mockAPICall)}>Get Data</button>
        </React.Fragment>
      );
    }
    
    function useFetch(action) {
      const [loading, setLoading] = useState(false);
      const [error, setError] = useState(null);
      const [data, setData] = useState(null);
    
      async function performAction(body) {
        try {
          setLoading(true);
          setData(null);
          setError(null);
          const data = await action(body);
          setData(data);
        } catch (e) {
          setError(e);
        } finally {
          setLoading(false);
        }
      }
    
      return [{ loading, data, error }, performAction];
    }
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    【讨论】:

      猜你喜欢
      • 2018-03-15
      • 2022-12-03
      • 2018-07-21
      • 2012-07-23
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 2019-08-02
      • 1970-01-01
      相关资源
      最近更新 更多