-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new useTracking
React hook
#124
Conversation
f8d9f3a
to
f5cfcf2
Compare
Fwiw I'm for this change. My team and I have been using react-tracking for about about 9 months and have a complete tracking system with it. We've also been writing about half our new components with hooks, so something like this would be really useful for us. We haven't upgraded to version 6.0 as of yet but I anticipate it will happen in the coming weeks. |
Thanks so much for this PR @damassi ! Will spend some more time reviewing and playing around with it. At a high level it looks great, but I'm wondering what your thoughts are around avoiding having to wrap the component in the Specifically the current decorator/HoC API allows for:
I haven't had a chance to really think through this design, but wanted to spit-ball some ideas with you. What are your thoughts on doing something like this: ( @juliusdelta your thoughts on this API would be greatly appreciated as well! ) export const Child = ({ name }) => {
const tracking = useTracking(
{
// (1) To support adding additional tracking context
// this object gets added to tracking context,
// so that any sub-components that Child renders get this data.
// Is this even possible? Or do we need to wrap/render something in the tree to add to its context?
childName: name,
additional: "properties",
could: "go here"
},
// (2) To support dispatching when a component mounts/renders (for the first time)
// is "dispatchOnMount" terminology confusing with hooks usage?
// is it better to be consistent with the "legacy" API or is there a better name here?
{ dispatchOnMount: contextData => true }
);
return <div onClick={() => tracking.trackEvent(/* ... */)} />;
}; But, is that export const ChildManualDispatchOnMount = ({ name }) => {
const tracking = useTracking({ childName: name });
// dispatchOnMount "manually"
useEffect(
() => {
// if it depends on contextual data, grab it first
const contextData = tracking.getTrackingData();
if (contextData.someThing) {
tracking.trackEvent({ mounted: "data" });
}
},
// note that "[]" is here to only fire once when the component mounts
// but leaving it empty causes React to warn:
// React Hook useEffect has a missing dependency: 'tracking'.
// Either include it or remove the dependency array. (react-hooks/exhaustive-deps)
// but if we do include `tracking` then this will fire repeatedly because
// (at least for this current PR) we get a new object every time: https://github.com/nytimes/react-tracking/pull/124/files#diff-06fcede0ecd25735ce64c15bd39106f4R16
//
// So maybe it's better to abstract this away as shown above?
[]
);
return <div onClick={() => tracking.trackEvent(/* ... */)} />;
};
Good question. What would it mean to deprecate them inside of react-tracking? In user-land if folks don't want to use decorators, they don't have to and can just compose |
@tizmagik - IMO HOC's are an abstraction that isn't going anywhere, and using them isn't mutually exclusive to hooks. I think it's perfectly reasonable to keep these things combined. It's also clear what's going on ("inject tracking context, which can then be pulled from the tree via a hook") with low complexity and backwards compatibility. In a version that we sketched out before opening this pr we had a function named |
Thanks @damassi that makes sense, I can totally see the argument for keeping it simple. The only other consideration for this API would be around the ergonomics of using the hooks API with the HoC API (you then have two "tracking" objects with similar interfaces, |
One thought about the hook API is that we could destructure, which would fairly clearly create a separation between the two if updated in the docs: const { trackEvent } = useTracking() But either way, my thinking was to ensure that the API was the same between the HOC and the hook so that users who wanted to unwrap / flatten-out child components and only rely on the hook could easily do so without needing to refactor inner-component logic. const WrappedChild = ({ tracking }) => {
...
tracking.trackEvent({ ... })
}
export default Child = track(WrappedChild) becomes const Child = props => {
const tracking = useTracking()
...
tracking.trackEvent({ ... })
} |
A small note on potentially using |
f5cfcf2
to
f0ffffc
Compare
f0ffffc
to
fc66c02
Compare
Sounds good! Updated with |
fc66c02
to
12a6b47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Thank you 🙏
Released as v7.0.0 🎉 Please holler (or open a new issue) if you see any problems. |
Nice one, @damassi ✨ |
Heads up, I'm seeing build issues with |
Ah yup, throwing this error, per #119:
|
Ah sorry about that. Ok prepping a revert PR and will publish as 7.0.1 |
Hm @damassi would you mind testing out updates to your core-js and babel config to see if it gets around your module errors? Specifically: #119 (comment) I'm wondering if that means folks who are already on core-js@3 if they'll start seeing errors if we revert that upgrade. (Also wondering if the proper solution here is using |
(👍 Will comment over in #119) |
@damassi I think we don’t need ReactTrackingContext to be exported as part of this hooks support, right? Just wanted to double check because I plan on removing that export in a separate PR. |
Nope, not necessary! I left it as a main export because it could be useful for other folks to build tooling on top of, but if they need it they could dig into a nested path. |
Closes #120
Note
Overview
This PR adds a new
useTracking
hook now that #118 has been implemented.Usage
And then the parent and children can pull it out via
useTracking
Since Hooks are only supported in React 16.8+, this requires a major version bump as it's a breaking change. Which leads to the question: should decorators be deprecated inside of
react-tracking
? The decorator proposal is still Stage II, and doesn't seem to be going anywhere.