简体   繁体   English

在 React 中使用 Hooks 获取 JSON 的正确方法是什么?

[英]What is the proper way to fetch JSON in React with Hooks?

So I have this application that displays random quotes that are pulled as JSON data from an API.所以我有这个应用程序,它显示从 API 中提取为 JSON 数据的随机引号。 It's my first foray into React so it is not really well done.这是我第一次接触 React,所以做得并不好。 Initially, I had all of my code stored in one component - but this was obviously not best practices because I had multiple things that could be split into components, ie a quote, a footer, a share button.最初,我将所有代码存储在一个组件中 - 但这显然不是最佳实践,因为我有多个可以拆分为组件的内容,即引用、页脚、共享按钮。

The issue I ran into when I split it up is that I didn't know how to share state between component files (for sharing to Twitter or other additional features) because I fetch the data like this :我在拆分时遇到的问题是我不知道如何在组件文件之间共享状态(用于共享到 Twitter 或其他附加功能),因为我获取的数据如下

/* this function accesses the API and returns a json */
export default function fetchQuote() {
    return fetch('https://programming-quotes-api.herokuapp.com/quotes/random') // fetch a response from the api
        .then((response) => { 
            let json = response.json(); // then assign the JSON'd response to a var
            return json; // return that bad boy
    });
}

which originally was called within the component class like so:它最初在组件类中被调用,如下所示:

/* component for the quotes */
export default class Quote extends React.Component {
    /* placeholder */
    constructor(props) {
        super(props);
        this.state = {
            quoteAuthor: "Rick Osborne", 
            quote: "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
        }
    }
    /* actually render things */
    render() {
        return (
            <div className="quotes">
                <h1>{this.state.quoteAuthor}</h1>
                <p>{this.state.quote}</p>
                <div className="button">
                    <button id="button" onClick={this.update}>New quote</button>
                </div>
            </div>
        );
    }

    /* async fetch the quotes and reassign the variables to them once processed */
    update = async() => {
        let response = await fetchQuote();
        console.log(response);
        this.setState({
            quoteAuthor: response.author,
            quote: response.en
        });
    };   
}

From my understanding, React's hooks seemed to solve my problem because I could use useState and useEffect which I tried to implement as follows (with the original fetchQuote() function untouched):根据我的理解,React 的钩子似乎解决了我的问题,因为我可以使用useStateuseEffect ,我尝试实现如下(原始fetchQuote()函数未受影响):

export default function Quote() {
    const [author, setAuthor] = useState("Rick Osborne");
    const [quote, setQuote] = useState(
        "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
        );
    let json = fetchQuote();

    useEffect (() => {
        setAuthor(json.author);
        setQuote(json.quote);
        console.log(json);
    });

    return (
        <div className="quotes">
            <h1>{author}</h1>
            <p>{quote}</p>
            <div className="button">
                <button id="button" onClick={async () => json = await fetchQuote()}>
                    New quote
                </button>
            </div>
        </div>
    )
}

However, no errors are thrown except the area in which the quote is displayed shows empty and calling console.log(json) within the useEffect simply returns但是,除了显示引号的区域显示为空并且在useEffect调用console.log(json)只会返回之外,不会引发任何错误

Promise { <state>: "pending" }
Promise { <state>: "pending" }

Am I using Hooks properly?我是否正确使用 Hook? How can I properly update the state with the JSON data?如何使用 JSON 数据正确更新状态?

It looks like the promise from fetch isn't resolving.看起来 fetch 的承诺没有解决。 Try this:尝试这个:

export default Quote = () => {
    const [author, setAuthor] = useState("Rick Osborne");
    const [quote, setQuote] = useState('');

    const fetchMyAPI = async () => {
      let json = await fetchQuote();
      setAuthor(json.author);
      setQuote(json.quote);
    }

    useEffect(() => {
     fetchMyAPI();
    }, []);

    return (
        <div className="quotes">
            <h1>{author}</h1>
            <p>{quote}</p>
            <div className="button">
                <button id="button" onClick={fetchMyAPI}>
                    New quote
                </button>
            </div>
        </div>
    )

This called fetchMyAPI onMount, and calls it whenever you click on New Quote .这称为 fetchMyAPI onMount,并在您单击New Quote时调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM