nytimes / react-tracking

🎯 Declarative tracking for React apps.

Home Page:https://open.nytimes.com/introducing-react-tracking-declarative-tracking-for-react-apps-2c76706bb79a

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't play nicely with Redux?

markgibaud opened this issue · comments

Hi - hopefully this is something small that i'm missing.

This is how I've initially integrated react-tracking into a ReactNative app also using redux:

App.tsx:

export default class App {
render() {
   <Provider store={store}>
   ...lots of other HoCs for various things
      <TrackedApp />
   </Provider>
    }
}

export const ConnectedApp = connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

export const TrackedApp = track(
  { app: 'myapp' },

  {
    dispatch: data => {
      console.log('tracking via TrackedApp...');
      console.log(data);
    }
  }
)(ConnectedApp);

MyComponent.tsx (rendered within App.tsx via react-navigation screens)

@track({ screen: 'MyComponent' })
export class MyComponent extends React.Component<MyComponentProps> {
  @track({ rendering: 'MyComponent' })
  render() {
   //normal react markup
  }
}

const mapStateToProps = state => {
  //normal redux state stuff
};

const mapDispatchToProps = dispatch => ({
  //normal dispatch props
});

export const MyComponentRoute = connect(
  mapStateToProps,
  mapDispatchToProps
)(MyComponent);

The problem is that when I run it something gets screwed with the HoC tree and I get this redux error:

Invariant Violation: Could not find "store" in either the context or props of "Connect(WithTracking(MyComponent))". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(WithTracking(MyComponent))".
  1. If I remove redux from the picture the tracking via the decorators works correctly.

  2. Curiously, if I convert over to using redux's connect as a decorator, it also works (both redux and tracking work fine).

@track({ screen: 'MyComponent' })
@connect(
  mapStateToProps,
  mapDispatchToProps
)
export class MyComponent {...}

However converting 100's of components over to using the redux decorator approach is not desirable for our codebase right now. Would prefer to get the redux connect HoC working with react-tracking's decorators.

Any guesses as to what's going on and where I can look into?

Ah ok, what also works is simply using the method version of track instead of the decorator on the class, while continuing to use decorators on the functions.

export const MyComponentRoute = track({ screen: 'MyComponent' })(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(MyComponent)
);

Will do this for now!

Hey @markgibaud -- please check out the latest release, v7.2.0 if you're still having issues. @bgergen PR may help fix this.

Hey @tizmagik

Hi, first of all awesome work!

Most of our need are covered (hierarchical definition of metrics context, handle async event -- with promise result, handle visible event, handle basic click, handle event args, ...) and the babel decorator syntax in order to wrap and inject context is so nice!

We have couple of place were it make sense for us to track event at the (Redux) reducer level, I'm guess this won't play well with React context, any suggestions?

Happy to move this in new ticket, but related to Redux, so..

We have couple of place were it make sense for us to track event at the (Redux) reducer level, I'm guess this won't play well with React context, any suggestions?

Hmm I'm not sure what you mean, why wouldn't it play well with React context? Under the hood, react-tracking does use React context to keep track of tracking objects.

If you can, yes, a new ticket/issue would be helpful to dig more into your specific question about using react-tracking from within a Redux reducer. Thanks!