英文:
Fetch api only works after second Enter key input NextJS
问题
组件应该在将输入键入搜索栏并单击回车键后,在控制台日志中显示JSON数据。它确实可以实现这一点,但它会滞后,直到再次单击回车键才会显示。接下来,当您更改搜索栏中的输入并单击回车键时,它将显示上一次搜索的结果。只有再次单击回车键才会获取当前搜索的结果。
对于搜索栏输入,您可以使用"Reinforcements"或"Contact"。
import { Box, Input } from "@chakra-ui/react";
import styles from "../styles/search.module.css";
import React, { useState } from "react";
export default function Search() {
const [cardName, setCardName] = useState("");
const [searchCard, setSearchCard] = useState("");
const handleChange = (event) => {
setCardName(event.target.value);
};
const handleKeyDown = (event) => {
if (event.key == "Enter") {
setSearchCard(cardName);
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${searchCard}`)
.then((response) => response.json())
.then((json) => console.log(json));
}
};
return (
<>
<Box className={styles.container}>
<Input
size="lg"
bg="#e8f1f2"
placeholder="Search for a card"
id="cardName"
name="cardName"
value={cardName}
onChange={handleChange}
onKeyDown={handleKeyDown}
className={styles.input}
></Input>
<ul className={styles.list"></ul>
</Box>
</>
);
}
英文:
How the component is suppose to work is after typing the input into the search bar and clicking on the enter key, it should show in the console log the json data. It does this, but it lags behind and won't show until clicking the enter key a second time. Next when changing the input in the search bar and clicking the enter key, it'll show the results of the previous search. You won't get the current search until you clicking the enter key again.
For the search bar input, you can use Reinforcements or Contact.
import { Box, Input } from "@chakra-ui/react";
import styles from "../styles/search.module.css";
import React, { useState } from "react";
export default function Search() {
const [cardName, setCardName] = useState("");
const [searchCard, setSearchCard] = useState("");
const handleChange = (event) => {
setCardName(event.target.value);
};
const handleKeyDown = (event) => {
if (event.key == "Enter") {
setSearchCard(cardName);
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${searchCard}`)
.then((response) => response.json())
.then((json) => console.log(json));
}
};
return (
<>
<Box className={styles.container}>
<Input
size="lg"
bg="#e8f1f2"
placeholder="Search for a card"
id="cardName"
name="cardName"
value={cardName}
onChange={handleChange}
onKeyDown={handleKeyDown}
className={styles.input}
></Input>
<ul className={styles.list}></ul>
</Box>
</>
);
}
答案1
得分: 1
以下是代码部分的翻译:
setSearchCard(cardName); // 第一行
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${searchCard}`) // 第二行
.then((response) => response.json())
.then((json) => console.log(json));
在第一行中,您更新了 searchCard
,然后在第二行中基于 searchCard
调用了您的 API。
在第一行中,您更新了 searchCard
,然后在第二行中基于 searchCard
调用了您的 API。
所以,您期望 searchCard
立即更新,但这不是 React 的工作方式。状态只在组件重新渲染时才会更新。
所以,在这里,您需要做以下更改:
setSearchCard(cardName);
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${cardName}`)
.then((response) => response.json())
.then((json) => console.log(json));
发生的情况是,假设您执行了 setCardName("first")
,然后调用了 API(因为组件尚未重新渲染),此时 cardName
仍然等于 ''
。当组件重新渲染时(因为 useState
钩子已更新),然后您再次点击 setCardName("second")
,然后再次调用 API(因为组件尚未重新渲染),此时 cardName
仍然等于 "first"
。这就是为什么您认为需要点击两次才能获得有效响应的原因。
英文:
look at this :
setSearchCard(cardName); // first line
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${searchCard}`) // second line
.then((response) => response.json())
.then((json) => console.log(json));
In the first line you update searchCard
then in the second line you call your API based on searchCard
.<br>
so you expected searchCard
to be updated immediately but this is not how react works the state will be updated only when the component rerenders<br>
so here what you have to do is :
setSearchCard(cardName);
fetch(`https://db.ygoprodeck.com/api/v7/cardinfo.php?name=${cardName}`)
.then((response) => response.json())
.then((json) => console.log(json));
So what is happening is if we suppose that you setCardName("first")
then you call the API (since the component didn't rerendered yet) cardName
is still equal to ''
<br> when the component rerenders (because a useState
hook is updated) and you click again to setCardName("second")
then you call the API (since the component didn't rerendered yet) cardName
is still equal to "first"
that's why you think you have to click twice to get a valid response
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论