Это правильный подход для заполнения свойств контекста приложения в React? - PullRequest
1 голос
/ 23 сентября 2019

Я успешно создал два контекста, по одному для каждого из двух различных модулей, которые я построил в React, используя функциональные компоненты и React Hooks.Стало очевидным, что существуют общие данные, которые требуются большинству / всем компонентам, которые я буду создавать.Вместо того чтобы делать вызовы GET с каждым компонентом верхнего уровня, я хочу реорганизовать эти общие данные и сохранить их в AppContext.Эти данные никогда не изменятся в сеансе для каждого пользователя.

Сначала я попытался поместить весь код заполнения непосредственно в AppContext, но это не сработало, поскольку контекст еще не был инициализирован.Итак, я создал компонент с именем InitAppData и обернул его следующим образом в App.js:

<AppContext>
  <Router />
  <InitAppData />
</AppContext>

InitAppData сам по себе довольно стандартен:

const InitAppData = () => {
  const { appStore,
          updateAppStore } = useContext(AppContext);

  // Populate the AWS Auth Token
  useGetAwsAuthToken();

  // Retrieve the Roles with a GET useFetch call
  const [{ data: rolesData, 
          status: rolesStatus,
          isLoading: rolesIsLoading, 
          isError: rolesIsError }] = useFetch(
    `${API_ROOT()}acct_mgmt/roles`,
    { }
  );

  // Process & populate the fetched Roles
  useEffect(() => {
    if (!rolesIsLoading && rolesStatus === 200) {
      appStore.roles = rolesData.roles;
    }
  }, [rolesIsLoading, rolesStatus]);

  // ... more population to go here ...

    return (null);
}

export default InitAppData;

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

Интересует мнение каждого об этом подходе,Если есть лучшая практика, мне всегда интересно учиться!

1 Ответ

1 голос
/ 23 сентября 2019

Посмотрите, поможет ли это.Это то, что я делал, и пока все работает нормально.

Ссылка на Песочницу: https://codesandbox.io/s/bold-currying-7fpyw

index.js

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import AppContext from "./AppContext";
import AllRoutes from "./AllRoutes";

function mockAPI() {
  return new Promise((resolve, reject) =>
    setTimeout(
      () =>
        resolve({
          propA: "This is some propA value",
          propB: "This is some propB value"
        }),
      1500
    )
  );
}

function App() {
  const [appState, setAppState] = useState(null);
  const [loading, setLoading] = useState(true);

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

  async function callMockAPI() {
    const response = await mockAPI();
    setAppState(response);
    setLoading(false);
  }

  return (
    <AppContext.Provider value={appState}>
      {loading ? (
        <div>I am waiting for the API to respond...</div>
      ) : (
        <Router>
          <AllRoutes />
        </Router>
      )}
    </AppContext.Provider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

AppContext.js

import React from "react";

const AppContext = React.createContext(null);

export default AppContext;

AllRoutes.js

import React from "react";
import { Route, Switch } from "react-router-dom";
import Home from "./Home";
import SomeComponent from "./SomeComponent";

function AllRoutes() {
  return (
    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/someComp" component={SomeComponent} />
    </Switch>
  );
}

export default AllRoutes;

Результат:

enter image description here

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