我做了一个钩子 useSendFormData ,当我使用它时,我得到了无效的钩子调用。
钩取
来自 SubmitForm 的数据
网址:字符串,
方法:发布或放置
success:如果成功则发送成功消息
id:不是必需的,但如果项目有 id,我会被添加到 api 调用中。
auth 默认为 false
问题是它丢失了渲染数据我不知道如何更好地描述它所以我制作了console.log ss 正如你在第二次通话中看到的,我得到了数据,但后来它消失了......
我的这个自定义钩子的代码:
const sendFormData = async ({
formData,
url,
method,
success,
id,
auth = false,
}) => {
const setPartData = (partialData) => setData({ ...data, ...partialData });
try {
let response;
if (method === "post") {
response = await axios.post(
`${SERVER_API}api/v1/${url}/${id ?? ""}`,
formData
);
} else if (method === "put") {
response = auth
? await fetchContext.authAxios.post(
`${SERVER_API}api/v1/${url}/${id ?? ""}`,
formData
)
: await axios.post(
`${SERVER_API}api/v1/${url}/${id ?? ""}`,
formData
);
}
setPartData({
data: response.data,
loading: false,
success,
error: null,
});
} catch (err) {
const { data } = err.response;
setPartData({
error: data.error,
success: null,
loading: false,
});
}
return data;
};
return {
sendFormData,
};
};
在哪里使用它,它从 SubmitForm 获取数据并使用它进行 api 调用,正如您在 ss 中看到的那样,我到达那里未定义:
const { sendFormData } = useSendFormData()
const handleForm = async (info) => {
// here you have your response.data returned
const data = await sendFormData({
formData: info,
url: "auth/forgot-password",
method: "post",
success: "A password reset message has been sent to your email",
});
console.log(data);
reset();
};
如果您能提供帮助,那就太棒了。如果您对此挂钩有任何优化提示,请告诉我。感谢您抽出宝贵时间。
编辑:编辑钩子但最后不返回数据值
答案 0 :(得分:1)
TL;DR
const setPartData = (partialData) => setData({ ...data, ...partialData });
应该改为
const setPartData = (partialData) => setData(data => ({ ...data, ...partialData }));
说明
setState
回调可以采用新状态(你做了什么),或者另一个回调(应该做什么)。您应该像这样传递一个回调,以确保 setPartialData(someData)
内对 sendFormData
的多次调用使用最新的 data
状态来更新自身(结合 partialData
)。这种方法是必要的,因为 const sendFormData = () => {}
已声明,其中使用的 data
变量是功能块外部的任何 data
(来自 const [data, setData] = useState()
)。此 data
不会在 sendFormData()
运行时更新,而是仅在组件渲染周期结束时更新。
换句话说,
const [data, setData] = useState(initialData);
const sendFormData = () => {
const setPartData = (partialData) => setData({ ...data, ...partialData });
setPartData(data1); // combines with initialData
setPartData(data2); // combines with initialData as well
}
请注意,您在哪里声明 const setPartData
并不重要,只要它可以访问 data
范围即可。
另一方面,
const setPartData = (partialData) => setData(data => ({ ...data, ...partialData }));
在需要运行 data
时使用最新的 setData()
状态,方法是通过内部回调访问它。
由于您构建的钩子可以返回 data
状态,因此一旦正确更新,您现在可以更好地使用它。
// App.js
const {data, sendFormData} = useSendFormData();
const sendAction = async (arg) => await sendFormData(arg);
return <>
<button onClick={sendAction}>send data</button>
{ data.success || someCondition ? data : null }
</>
当 this swr library 存在时重新发明轮子可能不是一个好主意,但我赞扬您努力使代码干燥。