Как организовать delay в React?

234
28 февраля 2018, 10:30

Есть сайдбар, перед тем как он открывается происходит рендеринг его чайлдов, что немного замедляет открытие. Я решил оттянуть рендеринг и после открытие 1-2 секунды показывать спиннер, а потом вместо него подставлять содержимое. То есть задать в стейте сайдбара какой-то флаг, который после открытия сайдабара 2-3 секунды будет true и соответственно я в рендере пропишу тернарным оператором условие при котором в этом случае буду отображать спиннер, по прошествии этого времени я буду делать setState и менять флаг, соответственно пойдет перерисовка на содержимое меню. попробовал прямо в рендере перед return:

if (visibleTagBar) {
            setTimeout(()=> this.setState({showDefaultLoader: false}), 3000);
        }

Но это неправильно. Пробовал в componentWillmount/DidMount-срабатывает слишком рано. Как можно реализовать данную штуку?

Answer 1

Идея с изменяемым параметром в state - очень правильная с точки зрения React-практик. Но есть ощущение, что вы могли где-то что-то не учесть.

после открытие 1-2 секунды показывать спиннер, а потом вместо него подставлять содержимое

Содержимое не будет рендерится (если под содержимым вы подразумеваете child'ы), пока оно не появится в React-дереве. Если вы прячете child'ы до изменения showDefaultLoader в true, то они не будут рендерится до тех пор, пока showDefaultLoader не будет равен true. В этом случае самое топорное решение - скрывать child'ы не прямым удалением из дерева, а путём выставления на них стиля opacity: 0 или даже visibility: hidden (если в их рендеринге не участвует DOM-дерево). Чтобы их скрыть таким образом - вы можете на их общий родитель навешивать отдельный класс при showDefaultLoader: false, который в стилях будет скрывать все дочерние child'ы.

попробовал прямо в рендере перед return

setTimeout(()=> this.setState({showDefaultLoader: false}), 3000);

Так не стоит делать. У вас render может вызываться множество раз при любом изменении state/props, и при этом будет запускаться этот таймер. Т.е. если за первые 2 секунды жизни компонента рендер отработал 20 раз, то вы запустите 20 копий этого таймера, каждая из которых выполнится, а при выполнении - последует перерендер, что опять же запустит снова этот таймер. В результате, браузер через некоторое время может зависнуть из-за постоянного увеличения числа таймеров. К тому же, при отключении компонента (когда вы перейдёте на другую страницу, где его нет) все ранее запущенные таймеры продолжат работать, и попытаются обновить state компонента, которого уже нет, что приведёт к массовым ошибкам в консоли.

READ ALSO
Помогите с кодировкой utf-8

Помогите с кодировкой utf-8

Через curl получаю строку, текст и сам ответ в utf-8, на выходе получаю (Ê ÷åðòó âñå! Áåðèñü è äåëàé - Ðè÷àðä Áðýíñîí), варианты конвертации в utf8 не помогли,...

228
Как создать тест на PHP?

Как создать тест на PHP?

ПриветствуюЕсть тест на php

285
DLE facebook share не работает как надо

DLE facebook share не работает как надо

Почему не подтягивает title https://prntsc/ijxbio вот статья http://yaskraveradio

203
Вычислить сумму факториалов [требует правки]

Вычислить сумму факториалов [требует правки]

Нужна помощь в решении задачи на php:

229