Извлечение случайных данных из API при нажатии кнопки — Реагируйте

#javascript #reactjs #api #fetch

Вопрос:

Когда отправляется запрос, ответ всегда один и тот же на перезагрузке страницы в Chrome, но случайный (как и должно быть) в FireFox. При нажатии кнопки данные всегда одинаковы после перезагрузки страницы. Я хочу делать запрос при каждом нажатии кнопки для хранения различных данных в цепочке состояний.

Я также попробовал это в vanilla js, и ответ тоже такой же.

Что заставляет данные всегда быть одинаковыми, а не случайными по запросу? Я сохраню ранее извлеченные данные в состоянии, но сначала нужно выяснить, почему это всегда одно и то же, я был бы признателен за любую помощь, поскольку я новичок в этих вызовах api и реагирую также.

App.js:

 import FetchColor from './common/FetchColor';
import ColorList from './components/ColorList';
import { useEffect, useState } from 'react';

function App() {
  const [colorData, changeColor] = useState('');

  const changeColorHandler = () => {
    FetchColor(changeColor);
  };

  useEffect(() => {
    FetchColor(changeColor);
  }, []);

  return (
    <div className='App'>
      <button onClick={changeColorHandler}>
        {colorData ? colorData.tags[0].name : 'Change Color'}
      </button>
      <ColorList color={colorData} />
    </div>
  );
}

export default App; 

FetchColor.js:

 const FetchColor = async (changeColor) => {
  const response = await fetch('https://www.colr.org/json/color/random');
  const data = await response.json();
  const [color] = data.colors;
  changeColor(color);
};

export default FetchColor; 

Ванильный JavaScript script.js:

 const fetchButton = document.getElementById('fetch-api');

fetchButton.addEventListener('click', fetchColorFunc);

async function fetchColorFunc() {
  const response = await fetch('https://www.colr.org/json/color/random');
  console.log(`Response: ${response}`);
  const data = await response.json();
  console.log(`Data: ${data}`);
} 

Комментарии:

1. Вы проверяли вкладку сеть в инструментах разработки? Возможно ли, что запросы кэшируются? Попробуйте добавить, например, случайную строку или текущую метку времени в запрос ( ?1234567 ).

2. Вы пробовали регистрировать результат запроса на выборку? Тогда вы можете быть уверены, что получаете правильные данные с сервера. Это также может быть связано с тем, как react перенаправляет, переопределяет обратные вызовы. И т.д. Попробуйте использовать обратный вызов

3. @SebastianRichner, это то же самое

4. @ZachSmith это не просто реакция, я также попробовал ванильный js, я просто добавил фрагмент кода выше

Ответ №1:

Это, скорее всего, связано с кэшированием. Если вы посмотрите на запросы в сетевой панели Chrome Инструментов разработчика, вы увидите, что запросы кэшируются и, следовательно, всегда возвращают одно и то же значение.

При необходимости Fetch принимает объект инициализации, содержащий пользовательские настройки, которые будут применены к запросу, включая кэш. Например, вы можете передать cache: "no-cache" или cache: "no-store" обойти кэширование (подробные сведения и различия см. в документации), и вы получите случайные результаты при каждом запросе. В качестве примера см. Следующий фрагмент кода:


 async function fetchColorFunc() {
  const response = await fetch('https://www.colr.org/json/color/random', { cache: "no-cache" });
  const data = await response.json();
  console.log(`Data: ${JSON.stringify(data)}`);
}

fetchColorFunc(); 

Ответ №2:

Chrome кэширует запрос. Вы можете увидеть это, если откроете инструменты разработчика и проверите на вкладке сеть. Вы увидите, что все последующие вызовы извлекаются из дискового кэша.

Вы можете либо добавить случайный запрос к URL-адресу

 const response = await fetch('https://www.colr.org/json/color/random?t=' Date.now());
 

или вы можете добавить cache-control заголовок со значением no-cache .

 const response = await fetch('https://www.colr.org/json/color/random', { headers : {"cache-control": "no-cache"}});
 

Но это вызовет предполетный запрос и потребует, чтобы сервер разрешил CORS из вашего источника.

Комментарии:

1. И то и другое работает! Спасибо за ответ, очень ценю это. 🙂