[英]How do deal with React hooks returning stale event handlers
我試圖弄清楚如何處理由鈎子返回的陳舊事件處理程序。 首先,當組件首次呈現時,它會向 api 發出異步請求以獲取憑據。 然后在對話框中按下提交按鈕以創建資源時使用這些憑據。 問題是即使在獲取憑據之后,對話框提交按鈕單擊事件處理程序的憑據也未定義。
憑證.js
import { useEffect } from 'react';
import { api } from './api';
export const useCredentials = (setCredentials) => {
useEffect(() => {
const asyncGetCredentials = async () => {
const result = await api.getCredentials();
if (result) {
setCredentials(result);
}
};
asyncGetCredentials().then();
}, []);
return credentials;
}
使用組件.js
import { useEffect, useRef, useCallback, useState } from 'react';
import { useCredentials } from './credentials';
import { createResource } from './resources';
import { useDialog } from './useDialog';
export const useComponent = () => {
const { closeDialog } = useDialog();
const [credentials, setCredentials] = useState();
useCredentials(setCredentials);
const credentialsRef = useRef(credentials);
useEffect(() => {
// logs credentials properly after they have been fetched
console.log(credentials)
credentialsRef.current = credentials;
}, [credentials]);
const createResourceUsingCredentials = useCallback(
async function () {
// credentials and credentialsRef.current are both undefined
// even when the function is called after the credentials
// have already been fetched.
console.log(credentials);
console.log(credentialsRef.current);
createResource(credentialsRef.current);
}, [credentials, credentialsRef, credentialsRef.current]
);
const onDialogSubmit = useCallback(
async function () {
await createResourceUsingCredentials();
closeDialog();
}, [
credentials,
credentialsRef,
credentialsRef.current,
createResourceUsingCredentials,
],
);
return {
onDialogSubmit,
}
}
試試這個方法
export const useCredentials = (setCredentials) => {
useEffect(() => {
const asyncGetCredentials = async () => {
const result = await api.getCredentials();
if (result) {
setCredentials(result);
}
};
asyncGetCredentials().then();
}, []);
}
export const useComponent = () => {
const { closeDialog } = useDialog();
const [credentials, setCredentials] = useState(); // new add
useCredentials(setCredentials);
....
}
為什么要增加復雜性,總是返回 function 並檢查 function 內部的credentials
export const useComponent = () => {
const { closeDialog } = useDialog();
const credentials = useCredentials();
// correctly logs undefined at first and updated credentials
// when they are asynchronously received from the api.
console.log(credentials);
async function createResourceUsingCredentials() {
createResource(credentials);
}
let onClickDialogSubmit = async () => {
if (credentials) {
await createResourceUsingCredentials();
closeDialog();
}
};
return {
onClickDialogSubmit,
}
}
我發現問題出在 useCredentials 掛鈎實現中。 如果請求已經在進行中,它會阻止對 api 的任何進一步的憑據請求。 由於此功能的執行不力,如果渲染了使用該掛鈎的超過 1 個組件,則只有首先渲染的組件才會獲得更新的憑據。 我更改了 useCredentials 掛鈎,使其訂閱全局 state(具有憑據),這樣無論哪個組件啟動請求,所有組件都會在請求完成時獲得憑據。 https://simbathesailor007.medium.com/debug-your-reactjs-hooks-with-ease-159691843c3a對調試此問題有很大幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.