我想创建一个将数据添加到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中这样做吗?通过hook / firebase完成此任务的合适方法是什么?
答案 0 :(得分:0)
查看是否适合您。
这是自定义钩子的好主意。
在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);