ReactTransitionGroup не работает с подключенным компонентом React-redux

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

Если я использую компонент Box, он работает. Он выводит в консоль componentWillEnter и componentWillLeave, когда мы нажимаем на кнопку.

Если я использую контейнер BoxContainer, он больше не работает. componentWillEnter и componentWillLeave специальные хуки жизненного цикла не вызываются.

{this.state.shouldShowBox && <BoxContainer/>}

Сборка Webpack выполнена корректно, ошибок в консоли нет, но ничего не выводит.

Я также пробовал использовать высокоуровневый API :ReactCSSTransitionGroup, и он работает с компонентами Box и BoxContainer. Но мне нужно использовать низкоуровневый API: ReactTransitionGroup.

У вас есть идея, почему это не работает, когда мы используем react-redux?

Используемая версия:

  • реагировать: 15.0.2
  • редукс: 3.5.2
  • реакция-редукс: 4.4.5

Код :

import React from 'react';
import {render} from 'react-dom';
import {Provider, connect} from 'react-redux';
import {createStore, compose, combineReducers} from 'redux';
import TransitionGroup from 'react/lib/ReactTransitionGroup';

// Box component
class Box extends React.Component {
  componentWillEnter(callback) {
    console.log('componentWillEnter');
    callback();
  }

  componentWillLeave(callback) {
    console.log('componentWillLeave');
    callback();
  }

  render() {
    return <div className="box"/>;
  }
}

// Boxe connected component
const BoxContainer = connect(null, {})(Box);

// App component
class App extends React.Component {
  state = {
    shouldShowBox: true
  };

  toggleBox = () => {
    this.setState({
      shouldShowBox: !this.state.shouldShowBox
    });
  };

  render() {
    return (
      <div>
        <TransitionGroup>
          {this.state.shouldShowBox && <BoxContainer/>}
        </TransitionGroup>
        <button className="toggle-btn" onClick={this.toggleBox}>
          toggle
        </button>
      </div>
    );
  }
}

// reducer
function reducer(state = [], action) {
  switch (action.type) {
    default:
      return state
  }
}

// store
const store = createStore(reducer);

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

person Louis Barranqueiro    schedule 07.05.2016    source источник


Ответы (2)


Это не должно работать, потому что connect превращает ваш компонент в «подключенный» объект, однако есть некоторые обходные пути, такие как подключиться к переходной группе

Создатель Redux Дэн Абрамов рассказал об проблеме.

Если быть до конца честным, я не хочу жестко кодировать поддержку групп переходов в connect(). Это очень специфический API, который не будет API анимации React и действует скорее как аварийный люк, пока не появятся лучшие решения. То, как он вызывает методы экземпляра для вложенного экземпляра, не очень хорошо согласуется с концептуальной моделью React.

Я бы посоветовал вам:

  • Либо напишите свою собственную оболочку вокруг connect(), как вы предложили

  • Или используйте более удобный для React подход к анимации, такой как https://github.com/chenglou/react-motion

Либо напишите свою собственную оболочку вокруг connect(), как вы предложили, либо используйте более удобный для React подход к анимации, такой как https://github.com/chenglou/react-motion

person QoP    schedule 07.05.2016

Мы также пытались сделать то же самое, соединив TransitionGroup с redux подключенным компонентом, например

<TransitionGroup>
  layerIds.map(id => ( <Layer ...>))
</TransitionGroup>

где Layer сам является подключенным компонентом redux.

Мы также пытались обернуть Layer сами, как

const WrappedLayer = (props) =>{
  return <TransitionGroup>
  <Layer {...props}/>
  </TransitionGroup>
}

И подключите его с помощью WrappedLayer, он будет работать только на этапе монтирования, например componentWillAppear и componentDidAppear, не будет работать на этапе размонтирования, поскольку при удалении слоя в пользовательском интерфейсе TransitionGroup также удаляется, тогда метод жизненного цикла, такой как componentWillLeave, никогда не будет запущен. .

Хорошая новость заключается в том, что мы наконец нашли очень удобную библиотеку react-move https://github.com/react-tools/react-move , который, по нашему мнению, лучше, чем react-motion, поскольку мы можем настраивать продолжительность, кривую анимации, и он очень чистый.

Надеюсь, это поможет вам, если у вас возникнут проблемы с использованием react-move, просто напишите мне.

person Kevin Li    schedule 18.09.2017