简体   繁体   English

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

[英]ReactTransitionGroup doesn't works with React-redux connected component

I'm working on a bigger project but I created this short example to illustrate the problem. 我正在做一个更大的项目,但我创建了这个简短的示例来说明问题。

If I use Box component, its works. 如果我使用Box组件,它的工作原理。 It outputs in the console componentWillEnter and componentWillLeave when we click on the button. 当我们单击按钮时,它将在控制台中输出componentWillEntercomponentWillLeave

If I use BoxContainer container, it doesn't work anymore. 如果我使用BoxContainer容器,它将不再起作用。 componentWillEnter and componentWillLeave special lifecycle hooks are not called. 不调用componentWillEntercomponentWillLeave特殊生命周期挂钩。

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

Webpack build is done correctly, no errors in the console, but It outputs nothing. Webpack构建正确完成,控制台中没有错误,但是没有输出。

I also tried with high-level API : ReactCSSTransitionGroup , and it works with Box and BoxContainer component. 我还尝试了高级API: ReactCSSTransitionGroup ,它可与BoxBoxContainer组件一起使用。 But I need to use the low-level API : ReactTransitionGroup . 但是我需要使用低级API: ReactTransitionGroup

Do you have an idea why it doesn't works when we use react-redux ? 您是否知道为什么当我们使用react-redux时它不起作用?

Version used : 使用的版本:

  • react : 15.0.2 反应: 15.0.2
  • redux : 3.5.2 redux: 3.5.2
  • react-redux : 4.4.5 react-redux: 4.4.5

Code : 代码:

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

That is not supposed to work because connect wraps your component into a "connected" object, however, there are some workarounds like connect-with-transition-group 那应该行不通,因为connect将您的组件包装成一个“ connected”对象,但是,有一些解决方法,例如connect-with-transition-group

The creator of Redux, Dan Abramov, has said this about the issue Redux的创建者Dan Abramov就此问题发表了这样的评论

To be completely honest I don't want to hardcode supports for transition groups into connect(). 老实说,我不想将对过渡组的支持硬编码到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. 这是一个非常具体的API,在没有更好的解决方案之前,它不会成为React动画API,其作用更像是逃生舱口。 The way it invokes instance methods on a nested instance does not align with React conceptual model very well. 它在嵌套实例上调用实例方法的方式与React概念模型不太吻合。

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 像您建议的那样围绕connect()编写您自己的包装器,或者对https://github.com/chenglou/react-motion等动画使用更易于使用的方法

We also tried to do the same thing, hooking up TransitionGroup with redux connected component, like 我们还尝试做同样的事情,将TransitionGroupredux连接的组件连接起来,例如

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

where Layer itself is a connected redux component. 其中Layer本身是连接的Redux组件。

We also tried wrap Layer ourselves like 我们还尝试将Layer包裹起来

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

And connect it using WrappedLayer , it will only work on mounting stage like componentWillAppear and componentDidAppear , will not work on unmounting stage, since when you delete a layer on UI, the TransitionGroup is also deleted, then life cycle method like componentWillLeave will never be triggered. 并使用WrappedLayer连接,它将仅在诸如componentWillAppearcomponentDidAppear挂载阶段起作用,而在卸载阶段不起作用,因为当您删除UI上的一个图层时, TransitionGroup也将被删除,那么像componentWillLeave这样的生命周期方法将永远不会被触发。

Good news is that we finally find a very handy library react-move https://github.com/react-tools/react-move , which we think is better than react-motion , since we can custom the duration, the animation curve, and it is very clean. 好消息是,我们终于找到了一个非常方便的库react-move https://github.com/react-tools/react-move ,我们认为它比react-motion更好,因为我们可以自定义持续时间,动画曲线,而且非常干净。

Hopefully, this will help you, if you meet any problem by using react-move , just msg me. 希望这对您有帮助,如果您通过使用react-move遇到任何问题,请留言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM