Как использовать хук GraphQL в базовом компоненте приложения в реакции без повторного рендеринга? - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь использовать Redux с GraphQL const sliceQuery = useQuery(ALL_SLICES) в React, но мне кажется, что я не могу использовать useEffect для минимизации рендеров из-за перехватов GraphQL и их обещания Object { data: {}, variables: {}, refetch: (), fetchMore: (), updateQuery: (), startPolling: (), stopPolling: (), subscribeToMore: (), loading: true, networkStatus: 1, … }. Поэтому вместо этого я вынужден обновить props.slices за пределами useEffect, поскольку мне приходится ждать, пока ловушка GraphQL завершит sh загрузку со следующим:

if (!sliceQuery.loading && props.slices === null) {
  const allSlices = sliceQuery.data.allSlices
  props.initializeSlices(allSlices)
  props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
}

Вот мое полное приложение. js component:

import React, { useEffect } from 'react'
import { initializeSlices } from './reducers/sliceReducer'
import { setCurrentSlice } from './reducers/currentSliceReducer'
import { connect } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { useQuery } from '@apollo/react-hooks'
import NavBar from './components/navBar/NavBar'
import Slice from './components/pages/Slice'
import About from './components/pages/About'
import Policies from './components/pages/Policies'
import Contact from './components/pages/Contact'
import './static/css/base.css'
import { ALL_SLICES } from './schemas'

const App = (props) => {
  console.log('App.js is ran')
  const sliceQuery = useQuery(ALL_SLICES)
  const splitUrl = window.location.href.split('/')
  if (!sliceQuery.loading && props.slices === null) {
    const allSlices = sliceQuery.data.allSlices
    props.initializeSlices(allSlices)
    props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
  }

  const getSliceById = (id) => {
    return props.slices.find(s => s._id === id)
  }

  if (!props.slices || !props.currentSlice) {
    return (
      <div>
        <h1>loading..</h1>
      </div>
    )
  }
  return (
    <div className="wrapper">
      <Router>
        <NavBar />
        <Route exact path="/" render={() => <Slice slice={getSliceById('5e2db26efa3d070ec879b0e9')} /> } />
        <Route path="/slice/:name/:id" render={({match}) => <Slice slice={getSliceById(match.params.id)} /> } />
        <Route path="/about" render={() => <About /> } />
        <Route path="/policies" render={() => <Policies /> } />
        <Route path="/contact" render={() => <Contact /> } />
      </Router>
    </div>
  );
}
const mapStateToProps = (state) => {
  return {
    slices: state.slices,
    currentSlice: state.currentSlice,
  }
}

export default connect(
  mapStateToProps,
  { initializeSlices, setCurrentSlice }
)(App)

Вот консольный журнал только загрузки страницы:

Сервер разработки отключен. При необходимости обновите sh страницу.

[HMR] Ожидание сигнала обновления от WDS ...

Приложение. js запущено

. / Src / Приложение. js Строка 1:17: 'useEffect' определено, но никогда не используется no-unused-va

Предупреждение. Методы рендеринга должны быть чистой функцией props и состояния; запуск обновлений вложенных компонентов из рендера не допускается. При необходимости вызвать вложенные обновления в componentDidUpdate. Проверьте метод рендеринга приложения.

Приложение. js запущено

Приложение. js запущено

Приложение. js запущено

1 Ответ

0 голосов
/ 04 февраля 2020

Вы по-прежнему можете использовать useEffect для выполнения ваших методов только тогда, когда ваши данные станут доступны.

const allSlices = 
    !sliceQuery.loading && props.slices === null 
        ? sliceQuery.data.allSlices 
        : null;

useEffect(() => {
    if(allSlices !== null) {
        props.initializeSlices(allSlices)
        props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
    }
}, [allSlices, props.initializeSlices, props.setCurrentSlice])

Это вызовет методы props.initializeSlices и props.setCurrentSlice только тогда, когда allSlices станет доступным.

Если эти методы также создаются во время рендеринга, вам может понадобиться использовать useCallback там, где они созданы, чтобы остановить их, вызывая хук useEffect для выполнения при последующих рендерингах.

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