Не удается обработать загрузку счетчика реакции с помощью useState

Я использую функциональный компонент, поэтому мне нужно использовать UseState для обработки состояний компонента. Пытаюсь показать счетчик при загрузке данных с помощью аксиомов:

import { Spinner } from 'react-bootstrap';

const MandatesPage = props => {

  const [mandates, setMandates] = useState([]);
  const [loading, setLoading] = useState(false); //  to handle spinner hide show

   useEffect(() => {
    setLoading(true);  // here loading is true
    console.log(loading)
    axios
        .get(`${config.api}/mandates`)
        .then(response => response.data["hydra:member"],setLoading(false)) // here loading is false
        .then(data => setMandates(data))
        .catch(error => console.log(error.response));
}, []);

 ...
  if (loading) return
    return (
        <Spinner animation="border" variant="primary" />
    );
}

return (
   .....  // return the other logic of my app
 )

}

Моя проблема в том, что счетчик не отображается, и я помещаю console.log (загрузка) после setLoading (true), но я получил значение false. введите здесь описание изображения


person Khaled Boussoffara    schedule 25.03.2020    source источник


Ответы (2)


Конечно, loading по-прежнему ложно, потому что параметр асинхронный и будет истинным только при следующем рендеринге.

Для следующего рендера будет возвращен счетчик загрузки, так как загрузка будет истинной, чем. Если для вызовов axios требуется меньше 16-32 мсек, что является нормальным кадром для каждого рендера в реакции, счетчик загрузки не будет отображаться, потому что для загрузки уже будет установлено значение false.

person Domino987    schedule 25.03.2020
comment
Итак, когда я должен снова установить загрузку false, чтобы показать счетчик? - person Khaled Boussoffara; 25.03.2020
comment
Нет, это нормально установить для него значение false после выполнения вызова, но вам не нужен счетчик, если вам не нужно ждать, верно? - person Domino987; 25.03.2020
comment
хорошо спасибо я попробую что-нибудь хорошее с большим количеством данных - person Khaled Boussoffara; 25.03.2020

Проблема в том, что вы пытаетесь выполнить асинхронную операцию синхронным способом. Вы должны подождать, пока ваш ответ API не вернется, что-то вроде этого:

useEffect(() => {
  async function fetchMyAPI() {
    let url = 'http://something/';
    let config = {};
    const response = await myFetch(url);
    console.log(response);
  }  

  fetchMyAPI();
}, []);

Применительно к вашему примеру:

useEffect(() => {
  setLoading(true);
  async function fetchOnAxios() {
   const response = await axios.get(`${config.api}/mandates`)
    // Down below inside this function
    // you can set the loading based on the response
  }
  fetchOnAxios()
}, []);

Я настоятельно рекомендую эту статью для дальнейшего чтения, в ней есть примеры и все такое.

person Inacio Schweller    schedule 25.03.2020
comment
спасибо за ваш вопрос, но я не понимаю разницы между вашими двумя кодами, пожалуйста - person Khaled Boussoffara; 25.03.2020
comment
Нет никакой разницы, первый - это просто пример того, как вы должны обрабатывать выборку данных внутри хука useEffect. Второй применяет ту же логику к вашему коду. После установки response вы можете выполнять любую логику, которую вы делали с .then и .catch - person Inacio Schweller; 25.03.2020
comment
Если вы хотите иметь хорошее представление о проблеме, которую пытаетесь решить, прочитайте связанную статью внизу моего ответа. - person Inacio Schweller; 25.03.2020