Данные, полученные с помощью ax ios, мерцают при загрузке страницы - PullRequest
0 голосов
/ 03 августа 2020

Я создаю новый маркетинговый веб-сайт для своей компании в Гэтсби, использую axios для извлечения данных из REST api для динамического отображения списка дилеров, а затем динамически отображаю контактную информацию выбранного дилера в сайт. Это делается путем установки повара ie, который содержит идентификатор дилера в API, а затем извлекает информацию этого дилера на основе повара ie. Однако я сталкиваюсь с проблемой, когда имя дилера, которое я сейчас показываю в заголовке, мигает при каждой загрузке страницы. Это выглядит плохо, поэтому мне интересно, есть ли способ либо кэшировать эти данные, либо не заставлять их извлекать их при каждой загрузке страницы и устранять мерцание. Я все еще в разработке, поэтому у меня он поставлен на Netlify здесь , и вы можете взглянуть на живую версию.

Вот мой крючок.

use-fetch.ts

import { useEffect, useState } from 'react';
import axios from 'axios';

export const useFetch = (url: string) => {
  const [status, setStatus] = useState('idle');
  const [data, setData] = useState([]);

  useEffect(() => {
    if (!url) return;
    const fetchData = async () => {
      setStatus('fetching');
      const result = await axios(url);
      setData(result.data);
      setStatus('fetched');
    };

    fetchData();
  }, [url]);

  return { status, data };
};

Затем я могу использовать это на страницах следующим образом:

const [query] = useState('https://jsonplaceholder.typicode.com/users/1/');
const url = query && 'https://jsonplaceholder.typicode.com/users/${cookie}';
const { data } = useFetch(url);

Это устанавливает начальное состояние users/1/, который будет отображать информацию для первого дилера, если не задан ie повар.

Я использую это в компоненте макета, и я могу передать опору data своему Header компонент.

app-layout.tsx

import React, { ReactNode, useEffect, useState } from 'react';

import Logo from '../../assets/svg/logo.svg';

import { Header } from '../header/Header';
import { Footer } from '../footer/Footer';
import { Devtools } from '../devtools/Devtools';

import s from './AppLayout.scss';

import { useCookie } from 'hooks/use-cookie';
import { useFetch } from 'hooks/use-fetch';

interface AppLayoutProps {
  menuItems: any;
  children: ReactNode;
}

const isDev = process.env.NODE_ENV === 'development';

// tslint:disable no-default-export
export default ({ children, menuItems }: AppLayoutProps) => {
  // copyright year
  const [year, setDate] = useState<any>();

  // setting cookie to be referenced in the useFetch hook, setting the query for dealer specific information
  const [cookie] = useCookie('one-day-location', '1');

  // the API call
  const [query, setQuery] = useState('https://jsonplaceholder.typicode.com/users/1/');
  const url = query && `https://jsonplaceholder.typicode.com/users/${cookie}`;
  const { data } = useFetch(url);

  const getYear = () => setDate(new Date().getFullYear());

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

  return (
    <div className={s.layout}>
      <Header menuItems={menuItems} data={data}></Header>

      {children}

      <Footer menuItems={menuItems} logo={<Logo />} year={year} />

      {isDev && <Devtools />}
    </div>
  );
};

И это мой хук use-cookie, на который есть ссылки во всех этих компонентах:

use-cook ie .ts

import { useState } from 'react';
import Cookies from 'universal-cookie';

/**
 * Custom hook creates and returns cookie values.
 */
export const useCookie = (key: string, value: string) => {
  const cookies = new Cookies();
  const [cookie] = useState(() => {
    if (cookies.get(key)) {
      return cookies.get(key);
    }
    cookies.set(key, value);
  });

  const updateCookie = (value: string) => {
    removeItem(value);
    cookies.set(key, value);
  };

  const removeItem = (key: string) => {
    cookies.remove(key);
  };

  return [cookie, updateCookie, removeItem];
};

Если вы заметили, он мерцает при каждой загрузке страницы. Есть ли способ хранить и отображать эти данные по-другому, чтобы этого не происходило?

Заранее спасибо.

1 Ответ

1 голос
/ 04 августа 2020

Итак, я смог найти лучшее решение, немного покопавшись. Вместо того, чтобы пытаться отлаживать созданный мной хук, я использую ax ios -hooks , который имеет все те же функции, которые мне нужны, но решает проблему. В моем макете данные выбираются следующим образом:

const [cookie, updateCookie] = useCookie('one-day-location', '1');

const [{ data, loading, error }] = useAxios(
  `https://jsonplaceholder.typicode.com/users/${cookie}`,
);

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

...