Как обрабатывать асинхронные вызовы Firebase с помощью хуков - PullRequest
1 голос
/ 05 июля 2019

Я хотел бы создать ловушку для добавления данных в базу данных пожарного депо. Я не уверен, что если я неправильно понимаю, как работают хуки или пожарный магазин, я новичок в обоих.

Внимание: Невозможно выполнить обновление состояния 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 никогда не устанавливается в ожидаемый ответ, однако запись в журнал после ожидания в обработчике выборки показывает, что я получаю ответ. Должен ли я делать это в useEffect? Каков подходящий способ выполнить эту задачу через ловушку / firebase?

1 Ответ

0 голосов
/ 05 июля 2019

Посмотрите, работает ли это для вас.

Это отличная идея для пользовательского хука.

enter image description here

Рабочий пример для 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...