Уведомить дочерние компоненты о переходном состоянии в TransitionGroup - PullRequest
1 голос
/ 11 апреля 2019

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

const { stepId, children } = this.props;

<TransitionGroup className="journey">
    <CSSTransition
        timeout={300}
        classNames="journey-step"
        unmountOnExit
        key={stepId}>
        <div className="journey-step">
            {children}
        </div>
    </CSSTransition>
</TransitionGroup>

Этовсе работает отлично, за исключением того, что дети должны запускать какую-то работу, как только они представлены.Очевидное решение состоит в том, чтобы начать эту работу при монтировании (используя componentDidMount() или подобное), но в некоторых случаях это приводит к обновлению пользовательского интерфейса во время эффекта перехода и вызывает неприятный UX.

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

Я использую ReactJS16,2;может быть, есть какие-то новые опции, доступные для меня?

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

1 Ответ

2 голосов
/ 12 апреля 2019

Используйте контекстный интерфейс API

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

// Create a context
const JourneyContext = React.createContext();

// Use the provider to pass the stepId down
const { stepId, children } = this.props;

<JourneyContext.Provider value={stepId}>
  <TransitionGroup className="journey">
    <CSSTransition
      timeout={300}
      classNames="journey-step"
      unmountOnExit
      key={stepId}>
      <div className="journey-step">
        {children}
      </div>
    </CSSTransition>
  </TransitionGroup>
</JourneyContext.Provider>

// If your child is a functional component you can use the useContext hook to get the current stepId
const stepId = useContext(JourneyContext);
if (stepId === THIS_STEP) {
  // Do something...
}

// If your child is a class then you can access the context in the render method like this:
render() {
  return (
    <JourneyContext.Consumer>
      {stepId => {
        if (stepId === THIS_STEP) {
          // Do something...
        }
      }}
    </JourneyContext.Consumer> 
  );
}

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

...