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

IT技术 javascript reactjs react-redux
2021-05-24 00:42:34

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

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

如果我使用BoxContainer容器,它将不再起作用。componentWillEnter并且componentWillLeave不会调用特殊的生命周期钩子。

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

Webpack 构建正确完成,控制台中没有错误,但它什么也没输出。

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

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

使用的版本:

  • react:15.0.2
  • 还原:3.5.2
  • react-redux: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')
);
2个回答

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

Redux 的创建者 Dan Abramov 已经对这个问题说过了

老实说,我不想将转换组的支持硬编码到 connect() 中。这是一个非常具体的 API,它不会成为 React 动画 API,它的作用更像是一个逃生舱,直到有更好的解决方案。它在嵌套实例上调用实例方法的方式与 React 概念模型不太一致。

我建议你:

要么像您建议的那样围绕 connect() 编写自己的包装器,要么使用更适合 React 的动画方法,例如 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,请给我留言。