ReactTransitionGroup 不适用于 React-redux 连接组件

ReactTransitionGroup doesn't works with React-redux connected component

我正在做一个更大的项目,但我创建了这个简短的示例来说明问题。

如果我使用 Box 组件,它的工作原理。它在控制台中输出 componentWillEntercomponentWillLeave 当我们点击按钮时。

如果我使用 BoxContainer 容器,它就不再起作用了。 componentWillEntercomponentWillLeave 特殊生命周期挂钩未被调用。

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

Webpack 构建正确完成,控制台中没有错误,但没有任何输出。

我也尝试使用高级 API :ReactCSSTransitionGroup,它适用于 BoxBoxContainer 组件。但是我需要使用低级 API :ReactTransitionGroup.

你知道为什么我们使用 react-redux 时它不起作用吗?

使用的版本:

代码:

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')
);

这不应该起作用,因为连接将您的组件包装到一个 "connected" 对象中,但是,有一些解决方法,例如 connect-with-transition-group

Redux 的创建者 Dan Abramov 曾说过 issue

To be completely honest I don’t want to hardcode supports for transition groups into connect(). This is a very specific API that is not going to be the React animation API and acts more like an escape hatch until there are better solutions. The way it invokes instance methods on a nested instance does not align with React conceptual model very well.

I would suggest you to:

Either write your own wrapper around connect() like you suggested Or use a more React-friendly approach to animations such as https://github.com/chenglou/react-motion

我们也尝试做同样的事情,将 TransitionGroupredux 连接的组件连接起来,比如

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

其中 Layer 本身是一个连接的 redux 组件。

我们也试过Layer

一样包裹自己
const WrappedLayer = (props) =>{
  return <TransitionGroup>
  <Layer {...props}/>
  </TransitionGroup>
}

并使用WrappedLayer连接它,它只会在componentWillAppearcomponentDidAppear这样的安装阶段工作,不会在卸载阶段工作,因为当你删除UI,TransitionGroup也被删除,那么像componentWillLeave这样的生命周期方法将永远不会被触发。

好消息是我们终于找到了一个非常方便的库 react-move https://github.com/react-tools/react-move ,我们认为它比 react-motion 更好,因为我们可以自定义持续时间,动画曲线,而且很干净。

希望这对您有所帮助,如果您在使用 react-move 时遇到任何问题,请给我发消息。