Как правильно показать загрузку во время выборки в пользовательском хуке магазина? (НЕТ РЕДУКСА) - PullRequest
1 голос
/ 25 марта 2020

У меня реализован следующий код (ПОЖАЛУЙСТА, имейте в виду, я не хочу использовать redux)

Мой глобальный хук хранилища:

// store.tsx - custom store hook
import { useState, useEffect } from "react";

let globalState = {};
let listeners = [];
let actions = {};

export const useStore = () => {
  const setState = useState(globalState)[1];

  const dispatch = async (actionIdentifier, payload) => { // needed to add async/await in order to wait the async/await in the custom hooks for actions, i.e. for fetching
    const newState = await actions[actionIdentifier](globalState, payload);
    globalState = { ...globalState, ...newState };

    for (const listener of listeners) {
      listener(globalState);
    }
  };

  useEffect(() => {     
    listeners.push(setState);        
    return () => {         
      listeners = listeners.filter((li) => li !== setState);          
    };
  }, [setState, shouldListen]);

  return [globalState, dispatch];
};

export const initStore = (userActions, initialState) => {
  if (initialState) {
    globalState = { ...globalState, ...initialState };
  }
  actions = { ...actions, ...userActions };
};

import { initStore } from "./store";

файл, отвечающий за действия загрузки

// loading-store.tsx
const configureStore = () => {
  const actions = {
    SET_LOADING_START: (currentState) => {
      return { loading: true };
    },
    SET_LOADING_END: (currentState) => {
      return { loading: false };
    },
  };

  initStore(actions, {
    loading: false,
  });
};

export default configureStore;

и файл, отвечающий за выборку:

// fetching-store.tsx
import { initStore } from "./store";
import { getData } from "src/api/ResourceService";

const configureStore = () => {
  function fetchData() {
    const fetch = async () => {
      try {
        const res = await getData();
        console.log("[FETCH] Data:", res.data);
        return res.data;
      } catch (err) {
        console.error("[FETCH] Error", err);
        return err;
      }
    };
    return fetch();
  }     

  const actions = {
    FETCH: async (currentState) => {
      const newData = await fetchData();
      return { myFetchedData: newData };
    },
  };

  initStore(actions, {
    myFetchedData: [],
  });
};

export default configureStore;

следующий файл index.tsx:

// index.tsx
import React from "react";
import ReactDOM from "react-dom";

import "./assets/css/simpl-newton-bootstrap.css";
import "../node_modules/react-grid-layout/css/styles.css";
import "../node_modules/react-resizable/css/styles.css";

import { BrowserRouter } from "react-router-dom";
import * as serviceWorker from "./serviceWorker";

import App from "./App";
import { ThemeProvider } from "src/context/ThemeContext";

import fetchingStore from "src/hooks-store/fetching-store";
import loadingStore from "src/hooks-store/loading-store";

fetchingStore();
loadingStore();

ReactDOM.render(
  <ThemeProvider>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </ThemeProvider>,
  document.getElementById("root")
);

serviceWorker.unregister();

ВОПРОС: как настроить загрузку на true / false во время выборки, которая выполняется в fetchiing-store.tsx

Это реализация в Компоненте, где я вызываю fetch:

// myComponent.tsx 
import React, { useEffect } from "react";

import { useStore } from "src/hooks-store/store";

const myComponent = () => {
  const [state, dispatch] = useStore();
  const data = state.myFetchedData;

  useEffect(() => {
    dispatch("FETCH");
  }, []);

  return (
    <>
      // some code where data will be used ...
    </>
  );
}

export default myComponent;

Я пытался поместить ее в useEffect of myComponent.tsx как:

...
useEffect(() => {
     dispatch("SET_LOADING_START");
     dispatch("FETCH");
   }, []);
...

, а затем вручную в fetching-store.tsx

...
const actions = {
  FETCH: async (currentState) => {
    const newData = await fetchData();
    return { myFetchedData: newData, loading: false };
  },
};

initStore(actions, {
  myFetchedData: [],
  loading: false,
});
...

Но это немного грязно. Если у кого-то есть лучшее решение или вариант? Другой вопрос, является ли вообще хорошей идеей использовать вызов async / await в хранилище действий?

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