React Hooks:useState with onClick 仅更新第二次单击按钮?
Posted
技术标签:
【中文标题】React Hooks:useState with onClick 仅更新第二次单击按钮?【英文标题】:React Hooks: useState with onClick only updating the SECOND time button is clicked? 【发布时间】:2019-10-12 15:43:00 【问题描述】:编辑:忘记了一个重要部分 - 如果您单击 Jeff A. Menges 旁边的按钮并检查控制台日志,就会发现这一点。
代码的重要部分是按钮代码的onClick中的“setFullResults(cardResults.data.concat(cardResultsPageTwo.data))”行。我认为它应该将 fullResults 设置为我告诉它的任何内容......除非它在您第一次单击它时不起作用。每次之后,它都会起作用,但不是第一次。这对下一组来说会很麻烦,因为我无法映射到未定义的数组,而且我不想告诉用户只需单击两次按钮即可获得实际的搜索结果。
我猜 useEffect 会起作用,但我不知道如何编写它或将它放在哪里。它显然不能在 App 功能组件的顶部工作,但我尝试将它放在其他任何地方都会给我一个错误。
我尝试了“this.forceUpdate()”,很多地方都推荐它作为快速修复(但建议不要使用 - 但我已经尝试了好几个小时),但是“this.forceUpdate( )" 无论我把它放在哪里都不是一个函数。
请帮助我在第一次单击此按钮时使其正常工作。
import React, useState, useEffect from "react";
const App = () =>
let artistData = require("./mass-artists.json");
const [showTheCards, setShowTheCards] = useState();
const [fullResults, setFullResults] = useState([]);
useEffect(() =>
setFullResults();
, []);
let artistDataMap = artistData.map(artistName =>
//console.log(artistName);
return (
<aside className="artist-section">
<span>artistName</span>
<button
className="astbutton"
onClick= function GetCardList()
fetch(
`https://api.scryfall.com/cards/search?unique=prints&q=a:"$artistName"`
)
.then(response =>
return response.json();
)
.then((cardResults) =>
console.log(cardResults.has_more)
if (cardResults.has_more === true)
fetch (`https://api.scryfall.com/cards/search?unique=prints&q=a:"$artistName"&page=2`)
.then((responsepagetwo) =>
return responsepagetwo.json();
)
.then(cardResultsPageTwo =>
console.log(`First Results Page: $cardResults`)
console.log(`Second Results Page: $cardResultsPageTwo`)
setFullResults(cardResults.data.concat(cardResultsPageTwo.data))
console.log(`Full Results: $fullResults`)
)
setShowTheCards(
cardResults.data
.filter(( digital ) => digital === false)
.map(cardData =>
if (cardData.layout === "transform")
return (
//TODO : Transform card code
<span>Transform Card (Needs special return)</span>
)
else if (cardData.layout === "double_faced_token")
return (
//TODO: Double Faced Token card code
<span>Double Faced Token (Needs special return)</span>
)
else
return (
<div className="card-object">
<span className="card-object-name">
cardData.name
</span>
<span className="card-object-set">
cardData.set_name
</span>
<img
className="card-object-img-sm"
alt=cardData.name
src=cardData.image_uris.small
/>
</div>
)
)
)
);
>
Show Cards
</button>
</aside>
);
);
return (
<aside>
<aside className="artist-group">
artistDataMap
</aside>
<aside className="card-wrapper">
showTheCards
</aside>
</aside>
);
;
export default App;
CodesAndBox:https://codesandbox.io/embed/compassionate-satoshi-iq3nc?fontsize=14
【问题讨论】:
每次点击都会加载结果,给我们展示一个重现的例子。 抱歉,累了 - 单击 Jeff A. Menges 旁边的按钮并检查控制台日志。 我无法在 Jeff A. Menges 的点击上重现。 您在设置状态后立即访问 fullResults,检查渲染中的 fullresults 它应该具有最新值。 您的 console.log 语句首先调用然后 setState。useEffect(() => console.log(fullResults); setFullResults(); );
【参考方案1】:
您可以尝试重构代码,例如 onClick 处理程序有一个合成事件。将此事件侦听器添加为类的一部分。使用箭头函数,这样您就不需要在构造函数中绑定此函数处理程序。获取数据后,尝试将状态设置为结果,并使用该状态在 render 方法中渲染 html 标记。当我运行这段代码时,我还在控制台中看到了一个错误,即子元素需要 key 属性。我已经看到您在渲染方法中使用 Array.prototype.map ,但是当您返回其中的 span 元素时,尝试添加一个关键属性,以便当 React diffing 算法遇到一个新元素时,它会降低检查某些节点的时间复杂度这个关键属性。
【讨论】:
【参考方案2】:useEffect(() =>
// call the functions which depend on fullResults here
setFullResults();
, [fullResults])
// 现在它将检查 fullResults 是否发生了变化,如果发生变化,则检查 useEffect 内部的函数是否取决于 fullResults
【讨论】:
以上是关于React Hooks:useState with onClick 仅更新第二次单击按钮?的主要内容,如果未能解决你的问题,请参考以下文章
React Hooks - 使用 useState 与仅使用变量
React Hooks --- useState 和 useEffect