【问题标题】:How to handle loading data using fetch and React Hooks如何使用 fetch 和 React Hooks 处理加载数据
【发布时间】:2021-06-23 17:42:33
【问题描述】:

我是 React 的新手,对 JavaScript 有点陌生。我正在做一个练习挑战,并试图确定如何使用异步函数处理useEffect,以便稍后在代码中使用数据。目前我的报价变量仍然是"",但我试图让它在ID为text的段落中与author段落中的作者一起呈现来自API的实际报价。有人可以帮忙吗?忽略我在 JSX 中反复使用 id。这就是挑战所要求的。谢谢。

代码如下,但这里是我迄今为止在 codepen.io 中挑战的链接:https://codepen.io/malbrecht13/pen/QWdNGYp?editors=0111

const App = () => {
  const [quote, setQuote] = React.useState('');
  const [author, setAuthor] = React.useState('');
  const [quoteNum, setQuoteNum] = React.useState(0);
  
  
  React.useEffect(() => {
    async function getQuotes() {
    const data = await fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json', {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    const json = await data.json();
    setQuote(json.quotes[quoteNum].quote);
    setAuthor(json.quotes[quoteNum].author);
    setQuoteNum(quoteNum + 1);
  }
    getQuotes();
  }, []);
  
    return (
    <div id="quote-box">
      <p id="text">{quote}</p>
      <p id="author">{author}</p>
      <a id="tweet-quote" href="twitter.com/intent/tweet">Tweet Quote</a>
      <button id="new-quote" >New Quote</button>
    </div>
  )
}

ReactDOM.render(
  <App/>,
  document.getElementById('root')
)

【问题讨论】:

  • 当然,但挑战必须在 codepen.io 中完成。
  • 您能否edit 您的问题并为您当前的方法提供codepen.io 链接?
  • 我添加了链接。
  • 谢谢。如果您使用 F12 打开开发者控制台,您会看到当前代码的错误,即 Access to fetch at 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json' from origin 'https://cdpn.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. 在 codepen.io 演示中尝试远程获取内容时,您可能很难解决 CORS 限制。
  • 在生产应用程序中,您不会遇到该问题,因为您获取的资源通常位于提供网页的同一来源。如果挑战是专门制作一个从这样的资源中获取的 codepen.io 演示,我认为请求一个不受 CORS 限制的挑战的资源 URL 是合理的。

标签: javascript reactjs fetch-api use-effect


【解决方案1】:

您的 fetch() 标头与提供的解决方案中的 $.ajax() 标头不匹配,因此您最终会收到 CORS 错误,从而阻止加载响应。你设置了Content-Type,而他们却设置了Accept

您还应该重新考虑有状态变量的组织,因为您只需要获取一次引号,而不是每次设置索引时:

const App = () => {
  const [quotes, setQuotes] = useState();
  const [index, setIndex] = useState(0);
  
  useEffect(() => {
    async function getQuotes() {
      const response = await fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json', {
        headers: {
          'Accept': 'application/json'
        }
      });
      const data = await response.json();
      setQuotes(data.quotes);
    }

    getQuotes();
  }, []);

  if (!quotes) return (
    <div id="quote-box">
      <p id="text">Loading...</p>
    </div>
  );

  const { quote, author } = quotes[index];
  const setNext = () => setIndex((index + 1) % quotes.length);

  return (
    <div id="quote-box">
      <p id="text">{quote}</p>
      <p id="author">{author}</p>
      <a id="tweet-quote" href="twitter.com/intent/tweet">Tweet Quote</a>
      <button id="new-quote" onClick={setNext}>New Quote</button>
    </div>
  );
}

【讨论】:

  • 谢谢,很有帮助!
猜你喜欢
  • 2021-10-11
  • 2019-04-26
  • 2020-11-07
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 2020-12-23
相关资源
最近更新 更多