异步调用 React Hook
2022-03-22
91
抱歉,这是 React 初学者的问题。我正在尝试使用 React Hook 来获取数据并将其异步返回给组件。
const CallSubmit = async () => {
return await useSubmitForm(tenantForm, datasetForm, entityForm)
}
const CallSubmitHook = async () => {
const submitStatus = await CallSubmit();
console.log(submitStatus)
if (submitStatus === true) {
setCurrentForm(5)
} else if (submitStatus === false) {
setCurrentForm(6)
}
}
useSubmitForm
是我遇到问题的钩子。使用此代码迭代,我收到以下错误:
无效的钩子调用。钩子只能在函数组件的主体内调用。
我已将钩子调用移至另一个函数以尝试修复此错误,但错误仍然存在。如果它需要位于函数的顶层,那么在提交表单后,我该如何有条件地调用它?
我尝试将获取功能放入
useEffect
中,但问题是我需要获取功能在将其分配给变量之前取回其响应。请告诉我如何最好地实现这一点?
编辑 根据 Dave 的回答,我重组了我的代码。
Hook(抱歉,这里很复杂。需要使用数据进行 3 次单独的 api 调用):
export default async function useSubmitForm(tenant, dataset, entity) {
let tenantRequestParams = {}
let datasetRequestParams = {}
let entityRequestParams = {}
const [isSending, setIsSending] = useState(false);
const [formPostResult, setFormPostResult] = useState()
const postFormData = async (tenant, dataset, entity) => {
setIsSending(true);
const result = await axios.get('token url')
.then((res) => {
token = res.data
tenantRequestParams = {
url: "api1",
config: {
headers: {
'Access-Control-Allow-Origin': '*',
'Authorization': `Bearer ${token}`,
}
},
body: JSON.parse(tenant),
};
datasetRequestParams = {
url: "api2",
config: {
headers: {
'Access-Control-Allow-Origin': '*',
'Authorization': `Bearer ${token}`,
}
},
body: JSON.parse(dataset),
};
entityRequestParams = {
url: "api3",
config: {
headers: {
'Access-Control-Allow-Origin': '*',
'Authorization': `Bearer ${token}`,
}
},
body: JSON.parse(entity),
};
}).then(() => {
console.log(tenantRequestParams.url,
tenantRequestParams.body,
tenantRequestParams.config)
function postTenant() {
return axios
.post(
tenantRequestParams.url,
tenantRequestParams.body,
tenantRequestParams.config
)
.then((res) => {
console.log(res);
return res;
})
.catch((error) => {
console.error(error);
return error;
});
}
function postDataset() {
return axios
.post(
datasetRequestParams.url,
datasetRequestParams.body,
datasetRequestParams.config
)
.then((res) => {
console.log(res);
return res;
})
.catch((error) => {
console.error(error);
return error;
});
}
function postEntity() {
return axios
.post(
entityRequestParams.url,
entityRequestParams.body,
entityRequestParams.config
)
.then((res) => {
console.log(res);
return res;
})
.catch((error) => {
console.error(error);
return error;
});
}
axios.all([postTenant(), postDataset(), postEntity()])
.then(res => {
return res;
}).catch(e => {
console.error(e)
return e;
})
});
setFormPostResult(result)
}
const postFormDataCallback = useCallback(postFormData, [])
return { isSending, success: formPostResult, postFormData: postFormDataCallback };
}
以及来自组件(简化版本):
import useSubmitForm from '../hooks/useSubmitForm';
export default function FormPage(props) {
const { isSending, success, postFormData } = useSubmitForm();
const [tenantForm, setTenantForm] = useState('');
const [datasetForm, setDatasetForm] = useState('');
const [entityForm, setEntityForm] = useState('');
return (
<div>
<Form (3 forms, sets values for each to state above)/>
<PrimaryButton type="button" onClick={() => {
postFormData(tenantForm, datasetForm, entityForm)
}}>Submit</PrimaryButton>
</div>
)
}
使用此实现,我遇到一个问题,即组件中的解构无法正常工作(所有 3 个都是未定义的
any
值)。我这里遗漏了什么吗?
1个回答
钩子属于您功能组件的范围,必须始终以相同的顺序调用。
406786905
更新
在上面的示例中,
useubmitform
是钩子。 (钩子以
使用
。)将钩子移至其所属的位置。不要将异步放在钩子前。这个想法是您调用钩子,在后台可以做一些工作。挂钩可以返回其他方法(例如,您可以在React组件中调用的PostTenantForm()。)
update2 这是一些非常粗糙的psudo代码。您需要阅读一些教程以跨越终点线,但这是轮廓。
412814876
Dave
2022-03-22