React Hooks:带有onClick的useState仅更新了第二时间按钮被单击了吗?

时间:2019-05-27 04:35:16

标签: javascript reactjs use-effect

编辑:忘记了重要的部分-如果您单击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

2 个答案:

答案 0 :(得分:0)

您可以尝试重构代码,例如onClick处理程序具有合成事件。将此事件侦听器添加为类的一部分。使用箭头函数,这样就不必在构造函数中绑定此函数处理程序。提取数据后,尝试将状态设置为结果,并使用该状态在render方法中呈现HTML标记。而且,当我运行这段代码时,我还发现控制台中的一个错误是子元素需要key属性。我已经看到您在render方法中使用Array.prototype.map,但是当您返回span元素时尝试添加一个key属性,这样当React diffing算法遇到一个新元素时,它会减少检查某些节点的时间复杂度此键属性。

答案 1 :(得分:-1)

useEffect(() => {
   // call the functions which depend on fullResults here
   setFullResults();
}, [fullResults])

//现在,它将检查 fullResults 是否已更改,如果已更改 useEffect 中的调用函数(取决于 fullResults