英文:
React custom hook does not give result of POST
问题
以下是您要翻译的内容:
The custom hook post method working fine at the same time the response adding state taking time.
console.log(jsonResult)
shows the response of POST method at the same time responseData
shows null
usePostQuery
import { useCallback, useState } from "react";
interface bodyData {
message: string,
author: string
}
const usePostQuery = (url: string, data?: bodyData ) => {
const [responseData, setResponseData] = useState();
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState('');
const callPost = useCallback( async (data: bodyData) => {
try {
setLoading(true);
const response = await fetch(url, {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: data.message,
userId: 15
})
});
const jsonResult = await response.json();
console.log('--------jsonResult---------');
console.log(jsonResult)
setResponseData(jsonResult);
} catch (error: any) {
setError(error.message);
} finally {
setLoading(false);
}
},
[url]
);
return { responseData, loading, error, callPost };
};
export default usePostQuery;
const { responseData, loading, error, callPost } = usePostQuery('https://jsonplaceholder.typicode.com/posts')
The responseData
is not giving post call response
useEffect(() => {
if (draftMessage && myMessage) {
// submitNewMessage()
console.log("post my message to server");
callPost({
message: myMessage,
author: "Mo"
});
if (loading === false) {
setMyMessage("");
setdraftMessage(false);
console.log("after ", responseData);
}
console.log("responseData ", responseData);
}
}, [draftMessage, myMessage]);
The fetch is successful because the console in side fetch response shows the API response.
英文:
The custome hook post method working fine at the same time the response adding state taking time.
console.log(jsonResult)
shows the response of POST method at the same time responseData
shows null
usePostQuery
import { useCallback, useState } from "react";
interface bodyData {
message: string,
author: string
}
const usePostQuery = (url: string, data?: bodyData )=> {
const [responseData, setResponseData] = useState();
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState('');
const callPost = useCallback( async (data: bodyData) => {
try {
setLoading(true);
const response = await fetch(url, {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: data.message,
userId: 15
})
});
const jsonResult = await response.json();
console.log('--------jsonResult---------');
console.log(jsonResult)
setResponseData(jsonResult);
} catch (error: any) {
setError(error.message);
} finally {
setLoading(false);
}
},
);
return { responseData, loading, error, callPost };
};
export default usePostQuery;
const { responseData, loading, error, callPost } = usePostQuery('https://jsonplaceholder.typicode.com/posts')
The responseData
is not giving post call response
useEffect(() => {
if (draftMessage && myMessage) {
// submitNewMessage()
console.log("post my message to server");
callPost({
message: myMessage,
author: "Mo"
});
if (loading === false) {
setMyMessage("");
setdraftMessage(false);
console.log("after ", responseData);
}
console.log("responseData ", responseData);
}
}, [draftMessage, myMessage]);
The fetch is successful because the console in side fetch response shows the API response.
答案1
得分: 1
你的自定义钩子没有问题。问题出在你的 effect 钩子中。
它只在它的依赖项更改时触发,即 draftMessage
和 myMessage
。它不会重新评估 loading
或 responseData
,因此只会在触发时看到它们的状态。
不太清楚你是如何使用 draftMessage
状态的。相反,我建议在你的提交处理程序中简单地触发 callPost
...
export default function App() {
const [myMessage, setMyMessage] = useState("");
const { responseData, loading, callPost } = usePostQuery(
"https://jsonplaceholder.typicode.com/posts"
);
const handleMyMessage = (val) => {
setMyMessage(val);
};
const handleSubmit = async (event) => {
event.preventDefault();
await callPost({ message: myMessage, author: "Mo" });
setMyMessage("");
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{loading ? (
<p>Loading...</p>
) : (
<ChatForm
onChange={handleMyMessage}
myMessage={myMessage}
handleSubmit={handleSubmit}
/>
)}
<pre>responseData = {JSON.stringify(responseData, null, 2)}</pre>
</div>
);
}
你的钩子控制了 loading
和 responseData
状态,所以你的组件真的没有太多事情要做。
英文:
There's nothing wrong with your custom hook. The issue is in your effect hook.
It only triggers when its dependencies change, ie draftMessage
and myMessage
. It does not re-evaluate loading
or responseData
so will only ever see their states at the time it is triggered.
It's really unclear what you're using the draftMessage
state for. Instead, I would simply trigger the callPost
in your submit handler...
export default function App() {
const [myMessage, setMyMessage] = useState("");
const { responseData, loading, callPost } = usePostQuery(
"https://jsonplaceholder.typicode.com/posts"
);
const handleMyMessage = (val) => {
setMyMessage(val);
};
const handleSubmit = async (event) => {
event.preventDefault();
await callPost({ message: myMessage, author: "Mo" });
setMyMessage("");
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{loading ? (
<p>Loading...</p>
) : (
<ChatForm
onChange={handleMyMessage}
myMessage={myMessage}
handleSubmit={handleSubmit}
/>
)}
<pre>responseData = {JSON.stringify(responseData, null, 2)}</pre>
</div>
);
}
Your hook controls the loading
and responseData
states so there's really very little for your components to do.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论