首页 > 解决方案 > 在 fetch 方法中加载状态不会更改为 true

问题描述

我一直在尝试为我的应用程序实现加载功能。我只是将加载状态从 false 更改为初始值,然后在开始获取时更改为 true,然后在结束数据获取时更改为 false。所以这应该显示我有条件地设置为在加载为真时渲染的加载元素。但它在我的 console.log 中显示该值始终为 false。

我尝试将 setState(true) 放在不同的位置,在 onClick 函数中,但它似乎没有切换为 true。


import React, { useState } from "react";
import { LANGUAGES } from '../config/languages'
import { BASEURL, APIKEY } from '../config/gavagai'

export function Input(props) {

    const [word, setWord] = useState("");
    const [language, setLanguage] = useState("");
    const [data, setData] = useState([])
    const [loading, setLoading] = useState(false);
    const url = BASEURL + '/' + language + '/' + word + '?additionalFields=SEMANTICALLY_SIMILAR_WORDS&apiKey=' + APIKEY;


    const fetchData = () => {
        giveWarning();
        setLoading(true);
        if (word && language) {

            fetch(url)
            .then(response => response.json())   
            .then(response => setData({ status: 'loaded', payload: response }), setLoading(false))
            .catch(error => setData({ status: 'error', error }))
            return data;
      };
    }

  return (
      <div>
      <h1>Gavagai Lexicon</h1>
      <div className="row">
      <label>
        Type your word here
      </label>
      </div>
      <div className="input-field col s5">
        <input
          type="text"
          value={word}
          onChange={e => setWord(e.target.value)}
        />
        </div>
        <div className="input-field col s3">
          <select className="browser-default" value={language} onChange={e => setLanguage(e.target.value)}>
              <option value="" disabled selected>Choose your language</option>
              { LANGUAGES.map((lang) => {
                  return(
                    <option value={lang.alpha2}>{lang.English}</option>
                  )
              })}
          </select>
          </div>
      <div className="button-space">
      <button className="btn waves-effect waves-light" onClick={() => fetchData()}>Search</button>
      </div>
      {
        loading ? <p>loading</p> : null
      }
      </div>

  );
}

Console.log 显示它没有切换为 true。我在这里想念什么?

标签: reactjsreact-hooks

解决方案


由于闭包,fetchData只能访问单词和语言变量的初始值。

您需要 useCallback( your function, [word, language] ) 来使用它们的当前值。

https://reactjs.org/docs/hooks-reference.html#usecallback

导出函数输入(道具){ ...

const fetchData = useCallback(
    () => {
        giveWarning();
        setLoading(true);
        if (word && language) {

            fetch(url)
            .then(response => response.json())   
            .then(response => setData({
                status: 'loaded',
                payload: response
            }), setLoading(false))
            .catch(error => setData({ status: 'error', error }))

            return data;
        };
    },
    [word, language]
)

...

推荐阅读