React Hooks: нажата кнопка "Использовать только с onClick" для обновления кнопки "ВТОРОЕ время"?

Редактировать: забыл важную часть - это заметно, если вы нажмете кнопку рядом с Джеффом А. Менгесом и посмотрите журнал консоли.

Важной частью кода является строка "setFullResults(cardResults.data.concat(cardResultsPageTwo.data))" в onClick кода кнопки. Я думаю, что СЛЕДУЕТ установить для fullResults все, что я скажу... за исключением того, что это не сработает при первом нажатии. Каждый раз после этого работает, но не в первый раз. Это будет проблемой для следующего набора, потому что я не могу отобразить неопределенный массив, и я не хочу просить пользователей просто дважды щелкнуть по кнопке, чтобы всплыли фактические результаты поиска.

Я предполагаю, что useEffect будет работать, но я не знаю, как его написать или куда его поместить. Это явно не работает в верхней части функционального компонента приложения, но в любом месте, я пытаюсь поставить его, выдает ошибку.

Я пробовал "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

1 ответ

Вы можете попробовать рефакторинг кода, как для обработчика onClick иметь синтетическое событие. Добавьте этот слушатель события как часть класса. Используйте функцию стрелки, так что вам не нужно связывать этот обработчик функции внутри конструктора. После извлечения данных попробуйте установить состояние для результата и использовать это состояние для визуализации HTML-разметки внутри метода render. И когда я запускаю этот код, я также видел одну ошибку в консоли, что дочерние элементы требуют ключевого атрибута. Я видел, что вы используете Array.prototype.map внутри метода render, но когда вы возвращаете элемент span внутри, попробуйте добавить ключевой атрибут, чтобы, когда алгоритм React diffing встречал новый элемент, он уменьшал сложность времени для проверки определенных узлов с помощью этот ключевой атрибут.

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

// теперь он проверит, изменилось ли fullResults, если изменилось, чем вызовы функций внутри useEffect, которые зависят от fullResults

Другие вопросы по тегам