Как правильно получить JSON в React with Hooks? - PullRequest
0 голосов
/ 10 марта 2020

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

Проблема, с которой я столкнулся при разделении, состоит в том, что я не знал, как делиться состоянием между файлами компонентов (для обмена в 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
    });
}

, который первоначально вызывался в классе компонентов следующим образом:

/* 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
        });
    };   
}

Насколько я понимаю, хуки React, похоже, решили мою проблему, потому что я мог использовать useState и useEffect, которые я попытался реализовать следующим образом (с исходной функцией 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>
    )
}

Однако никаких ошибок не возникает, за исключением области, в которой отображается цитата, отображается пустое и вызов console.log(json) внутри useEffect просто возвращает

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

Правильно ли я использую крючки? Как правильно обновить состояние данными JSON?

1 Ответ

2 голосов
/ 10 марта 2020

Похоже, обещание от fetch не решается. Попробуйте это:

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>
    )

Это называется fetchMyAPI onMount и вызывает его всякий раз, когда вы нажимаете New Quote.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...