Как мне разрешить это предупреждение от реакции, когда мой хук useEffect срабатывает после мутации реагировать-apollo? - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть список «карточек» в моем пользовательском интерфейсе, где в любой момент времени может быть развернута только одна карточка. В этом списке есть запрос react-apollo, который просматривает список заданий и возвращает реквизит, помечающий следующее незавершенное задание (nextJobId). Этот реквизит отслеживается хуком useEffect, который обновляет расширенную карту при обновлении реквизита nextJobId.

Внутри каждой карты есть кнопка, которая запускает мутацию react-apollo, которая обновляет базу данных (установка job.done в значение true), которая, в свою очередь, обновляет реквизит nextJobId. Как только это происходит, карта, содержащая только что нажатую кнопку, сворачивается, уничтожая кнопку.

Кажется, это вызывает следующую ошибку:

react-dom.development.js?61bb:507 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

Я полагаю, что происходит то, что кеш apollo обновляется до завершения мутации (если я добавлю функцию onCompleted к компоненту Mutation, он никогда не будет запущен).

Вот крючок:

useEffect(() => {
  client.writeData({
    data: {
      openVisitId: nextJobId
    }
  })
}, [nextJobId])

А вот и мутация:

mutation FinishJob($visitId: ID!) {
  updateJobInstance(data: { done: true }, where: { id: $visitId }) {
    done
    id
  }
}

До сих пор я разработал два способа решения этой проблемы:

1) Добавьте setTimeout к крючку:

useEffect(() => {
  setTimeout(() => {
    client.writeData({
      data: {
        liveVisitId: nextJobId,
        openVisitId: nextJobId
      }
    })
  })
}, [nextJobId])

Понятия не имею, почему это работает.

2) Удалите done из мутации (которая обходит прямое обновление кэша, я считаю) и используйте refetchQueries для повторного получения основного списка:

mutation FinishJob($visitId: ID!) {
  updateJobInstance(data: { done: true }, where: { id: $visitId }) {
    id
  }
}
<Mutation mutation={FinishJob} refetchQueries={['CardList']}>...</Mutation>

Это наводит меня на мысль, что каким-то образом оптимистично обновляется кэш, что приводит к уничтожению нажатой кнопки до того, как мутация действительно завершится. Это тот случай? И если да, то есть ли способ сказать react-apollo не обновлять кэш, пока мутация не завершится?

1 Ответ

0 голосов
/ 10 апреля 2019

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

Поэтому, чтобы предотвратить его, целесообразно использовать _isMounted.

function SomeName(){
    const _isMounted = false;

    useEffect(() => {
        _isMounted = true; //this is equivalent of componentDidMoun()
        return () => {
            _isMounted = false; //this is equivalent of componentWillUnmount()
        }
    }, [])
}

итеперь каждый раз, когда вам нужно обновить состояние, вы проверяете, смонтировано ли оно, чтобы обновить состояние

if(_isMounted)
{
    this.setState({
        //your data
    })
}
...