martyjs / marty

A Javascript library for state management in React applications
http://martyjs.org
MIT License
1.09k stars 77 forks source link

Compatibility with ReactTransitionGroup #353

Closed duro closed 8 years ago

duro commented 9 years ago

I am trying to implement transitions between pages in in my app. I do not want to use CSS transition, but plain old JS transition. React provides ReactTransitionGroup for this, and it uses the following lifecycle events when components enter and leave:

componentWillAppear()
componentWillEnter()
componentWillLeave()

I have this working when transitioning between two components that do not implement the Marty Container pattern. But when I try to move between components that implement Container, ReactTransitionGroup cannot find the the above lifecycle events, event though they are implemented on the component.

Any idea how to get this working?

taion commented 9 years ago

The container works by wrapping another component around your child component. We forward the standard React lifecycle methods, but we don't forward those. For now, you'll need to explicitly pass in additional keys to the container to call those on the child, e.g.

createContainer(
  MyComponent,
  {
    fetch: { /* ... */ },

    componentWillAppear() {
      this.getInnerComponent().componentWillAppear()
    }
  }
);

See http://martyjs.org/api/containers/index.html#other-options

duro commented 9 years ago

Tried this, and it seems to be working sporadically. I am often getting the following error:

Uncaught TypeError: Cannot read property 'componentWillEnter' of undefined

It appears that at the time the lifecycle event is called, this.getInnerComponent() is returning undefined. I tried wrapping the call like this:

module.exports = Marty.createContainer(About, {
  listenTo: [...],
  fetch: {...},
  componentWillAppear(cb) {
    if (this.getInnerComponent()) {
      this.getInnerComponent().componentWillAppear(cb)
    }
  },
  componentWillEnter(cb) {
    if (this.getInnerComponent()) {
      this.getInnerComponent().componentWillEnter(cb)
    }
  },
  componentWillLeave(cb) {
    if (this.getInnerComponent()) {
      this.getInnerComponent().componentWillLeave(cb)
    }
  }
})

And the inner lifecycle events never get called.

Thoughts?

duro commented 8 years ago

@taion Any time to look at this? Getting Marty to work with ReactTransitionGroup is the final thing stopping me from being able to do page transitions on my app.

taion commented 8 years ago

Okay, what's happening is this - the container doesn't actually render the inner component until all of its fetches are resolved; it just doesn't render anything, so there's no inner component to animate.

Can you set up the transitions around the inner component? Alternatively, you'd need to explicitly specify a pending that will call done.

duro commented 8 years ago

The structure of our app is page oriented. And the pages are often what are wrapped in Marty Containers. Our react-router is responsible for the page switches. So it is our main App component where the TransitionGroup lives. This would make it impossible to Wrap the inner component in the TransitionGroup, as it must happen on the parent that switches out the pages.

I will explore the pending approach.

taion commented 8 years ago

Any update on this? Can we close this issue?

duro commented 8 years ago

Not yet, have not had time to test. Feel free to close and I will reopen if I still have issues.

On Friday, July 31, 2015, Jimmy Jia notifications@github.com wrote:

Any update on this? Can we close this issue?

— Reply to this email directly or view it on GitHub https://github.com/martyjs/marty/issues/353#issuecomment-126663924.