Как получить данные в компоненте реакционной JS? - PullRequest
0 голосов
/ 22 апреля 2020

Я занимаюсь разработкой приложения React JS, Redux, GraphQL, TypeScript.

И я хотел бы знать, как вызвать функцию, которая извлекает данные и обновляет состояние через GraphQL из моего контейнера.

Имя действия, которое загружает данные через GraphQL: appActions.getAppData ();

Но оно вызывает бесконечный refre sh l oop, потому что это срабатывает (StatusActions.startAppLoading ()); который также обновляет состояние.

Я хотел бы знать, как решить эту проблему или как переписать /Main/index.tsx как компонент класса и вызвать startAppLoading () из componentDidMount ().

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

App Structure

main.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { configureStore } from 'app/store';
import { Router } from 'react-router';
import { App } from './app';

// prepare store
const history = createBrowserHistory();
const store = configureStore();

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <App />
    </Router>
  </Provider>,
  document.getElementById('root')
);

app / index.tsx

import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { App as Main } from 'app/containers/Main';
import { hot } from 'react-hot-loader';

let currentContainer = Main;

export const App = hot(module)(() => (
  <Switch>
    <Route exact path="/" component={currentContainer} />
    <Route path="*">
      <Redirect to="https://google.com" />
    </Route>
  </Switch>
));

app / Containers / Main / index.tsx

import React from 'react';
import style from './style.css';
import { RouteComponentProps } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { useTodoActions } from 'app/actions';
import { useAppActions } from 'app/actions';
import { RootState } from 'app/reducers';
import { Header, TodoList, Footer } from 'app/components';

export namespace App {
  export interface Props extends RouteComponentProps<void> {}
}

export const App = ({ history, location }: App.Props) => {
  const dispatch = useDispatch();
  const appActions = useAppActions(dispatch);

const { apps } = useSelector((state: RootState) => {
    return {
      apps: state.apps
    };
  });
  appActions.getAppData();

  return (
    <div className={style.normal}>
      <Header />
      <TodoList appActions={appActions} apps={apps} />
      <Footer />
    </div>
  );
};

app / actions /apps.ts

export const getAppData = () => {
    let appKey = 'interpegasus';
    return (dispatch: Dispatch) => {
      dispatch(StatusActions.startAppLoading());
      debugger;
      apolloClient
        .query({
          query: gql`
            query getApp($appKey: String!) {
              getApp(id: $appKey) {
                id
                name
                domain
              }
            }
          `,
          variables: {
            appKey: appKey
          }
        })
        .then((result) => {
          debugger;
          if (result.data.apps.length > 0) {
            dispatch(populateAppData(result.data.apps[0]));
          }
          dispatch(StatusActions.endAppLoading());
        })
        .catch((error) => {
          dispatch(StatusActions.endAppLoading());
          console.log({
            error: error
          });
        });
    };
  };

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

В Main/index.tsx вы звоните appActions.getAppData();, что приведет вас к actions/apps.ts. Здесь вы делаете dispatch(StatusActions.startAppLoading());, который обновит состояние и повторно отобразит `` Main / index.tsx`. Затем вы снова вызываете getAppData () и l oop продолжает приводить к бесконечному l oop.

Вызывать API только если не loading.

что-то вроде это:

  ...
  const { apps, loading } = useSelector((state: RootState) => {
    return {
      apps: state.apps,
      loading: state.loading // <----- replace with your actual name of your state 
    };
  });

  if(!loading){
    appActions.getAppData();
  }
  ...
1 голос
/ 22 апреля 2020

Вы должны поместить свои appActions.getAppData() в useEffect крючки вот так

useEffect(()=>{

 appActions.getAppData()

},[])

проверить официальные документы Представляем крючки

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