Skip to content

Commit 1d79924

Browse files
authored
Updates (#83)
* update deps, readme tweaks * prefer spread * drop 6 for 10
1 parent f4c96e9 commit 1d79924

File tree

5 files changed

+53
-69
lines changed

5 files changed

+53
-69
lines changed

Diff for: .travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: node_js
22
node_js:
3-
- 6
43
- 8
4+
- 10
55
script: npm run lint && npm test && npm run build

Diff for: README.md

+29-41
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ npm install --save react-tracking
1616
```
1717

1818
## Usage
19+
1920
`@track()` expects two arguments, `trackingData` and `options`.
21+
2022
- `trackingData` represents the data to be tracked (or a function returning that data)
2123
- `options` is an optional object that accepts three properties:
2224
- `dispatch`, which is a function to use instead of the default dispatch behavior. See the section on custom `dispatch()` later in this document.
@@ -36,7 +38,7 @@ The `@track()` decorator will expose a `tracking` prop on the component it wraps
3638

3739
// function to call to grab contextual tracking data
3840
getTrackingData: PropTypes.func,
39-
})
41+
});
4042
}
4143
```
4244

@@ -51,34 +53,30 @@ Alternatively, if you want to just silence proptype errors when using [eslint re
5153
```json
5254
{
5355
"rules": {
54-
"react/prop-types" : ["error", { "ignore": ["tracking"] }]
56+
"react/prop-types": ["error", { "ignore": ["tracking"] }]
5557
}
5658
}
5759
```
5860

5961
### Usage as a Decorator
62+
6063
`react-tracking` is best used as a `@decorator()` using the [babel decorators plugin](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy).
6164

62-
The decorator can be used on React Classes and on methods within those classes. If you use it on methods within these classes, make sure to decorate the class as well.
65+
The decorator can be used on React Classes and on methods within those classes. If you use it on methods within these classes, make sure to decorate the class as well.
6366

6467
```js
6568
import React from 'react';
6669
import track from 'react-tracking';
6770

6871
@track({ page: 'FooPage' })
6972
export default class FooPage extends React.Component {
70-
7173
@track({ action: 'click' })
7274
handleClick = () => {
7375
// ... other stuff
74-
}
76+
};
7577

7678
render() {
77-
return (
78-
<button onClick={this.handleClick}>
79-
Click Me!
80-
</button>
81-
);
79+
return <button onClick={this.handleClick}>Click Me!</button>;
8280
}
8381
}
8482
```
@@ -90,23 +88,24 @@ You can also track events by importing `track()` and wrapping your stateless fun
9088
```js
9189
import track from 'react-tracking';
9290

93-
const FooPage = (props) => {
91+
const FooPage = props => {
9492
return (
95-
<div onClick={() => {
93+
<div
94+
onClick={() => {
9695
props.tracking.trackEvent({ action: 'click' });
9796

9897
// ... other stuff
9998
}}
10099
/>
101-
)
102-
}
100+
);
101+
};
103102

104103
export default track({
105-
page: 'FooPage'
104+
page: 'FooPage',
106105
})(FooPage);
107106
```
108107

109-
This is also how you would use this module without `@decorators`, although this is obviously awkward and the decorator syntax is recommended.
108+
This is also how you would use this module without `@decorators`, although this is obviously awkward and the decorator syntax is recommended.
110109

111110
### Custom `options.dispatch()` for tracking data
112111

@@ -118,7 +117,7 @@ For example, to push objects to `window.myCustomDataLayer[]` instead, you would
118117
import React, { Component } from 'react';
119118
import track from 'react-tracking';
120119

121-
@track({}, { dispatch: (data) => window.myCustomDataLayer.push(data) })
120+
@track({}, { dispatch: data => window.myCustomDataLayer.push(data) })
122121
export default class App extends Component {
123122
render() {
124123
return this.props.children;
@@ -166,7 +165,6 @@ class FooPage extends Component { ... }
166165

167166
Will dispatch the following data (assuming no other tracking data in context from the rest of the app):
168167

169-
170168
```
171169
{
172170
event: 'pageDataReady',
@@ -176,7 +174,7 @@ Will dispatch the following data (assuming no other tracking data in context fro
176174

177175
### Top level `options.process`
178176

179-
When there's a need to implicitly dispatch an event with some data for *every* component, you can define an `options.process` function. This function should be declared once, at some top-level component. It will get called with each component's tracking data as the only argument. The returned object from this function will be merged with all the tracking context data and dispatched in `componentDidMount()`. If a falsy value is returned (`false`, `null`, `undefined`, ...), nothing will be dispatched.
177+
When there's a need to implicitly dispatch an event with some data for _every_ component, you can define an `options.process` function. This function should be declared once, at some top-level component. It will get called with each component's tracking data as the only argument. The returned object from this function will be merged with all the tracking context data and dispatched in `componentDidMount()`. If a falsy value is returned (`false`, `null`, `undefined`, ...), nothing will be dispatched.
180178

181179
A common use case for this is to dispatch a `pageview` event for every component in the application that has a `page` property on its `trackingData`:
182180

@@ -198,13 +196,13 @@ When `Page2` mounts, nothing will be dispatched.
198196
199197
### Tracking Asynchronous Methods
200198
201-
Asynchronous methods (methods that return promises) can also be tracked when the method has resolved or rejects a promise. This is handled transparently, so simply decorating a asynchronous method the same way as a normal method will make the tracking call _after_ the promise is resolved or rejected.
199+
Asynchronous methods (methods that return promises) can also be tracked when the method has resolved or rejects a promise. This is handled transparently, so simply decorating an asynchronous method the same way as a normal method will make the tracking call _after_ the promise is resolved or rejected.
202200
203201
```js
204202
// ...
205203
@track()
206204
async handleEvent() {
207-
await asyncCall(); // returns a promise
205+
return await asyncCall(); // returns a promise
208206
}
209207
// ...
210208
```
@@ -229,31 +227,25 @@ import track from 'react-tracking';
229227

230228
// In this case, the "page" tracking data
231229
// is a function of one of its props (isNew)
232-
@track((props) => {
233-
return { page: props.isNew ? 'new' : 'existing' }
230+
@track(props => {
231+
return { page: props.isNew ? 'new' : 'existing' };
234232
})
235233
export default class FooButton extends React.Component {
236-
237234
// In this case the tracking data depends on
238235
// some unknown (until runtime) value
239236
@track((props, state, [event]) => ({
240237
action: 'click',
241-
label: event.currentTarget.title || event.currentTarget.textContent
238+
label: event.currentTarget.title || event.currentTarget.textContent,
242239
}))
243-
handleClick = (event) => {
240+
handleClick = event => {
244241
if (this.props.onClick) {
245242
this.props.onClick(event);
246243
}
247-
}
244+
};
248245

249246
render() {
250-
return (
251-
<button onClick={this.handleClick}>
252-
{this.props.children}
253-
</button>
254-
);
247+
return <button onClick={this.handleClick}>{this.props.children}</button>;
255248
}
256-
257249
}
258250
```
259251
@@ -302,7 +294,7 @@ Further runtime data, such as the component's `props` and `state`, are available
302294
303295
```js
304296
@track((props, state) => ({
305-
action: state.following ? "unfollow clicked" : "follow clicked"
297+
action: state.following ? "unfollow clicked" : "follow clicked",
306298
name: props.name
307299
}))
308300
handleFollow = () => {
@@ -324,18 +316,15 @@ import track from 'react-tracking';
324316
const randomId = Math.floor(Math.random() * 100);
325317

326318
return {
327-
page_view_id: randomId
328-
}
319+
page_view_id: randomId,
320+
};
329321
})
330322
export default class AdComponent extends React.Component {
331323
render() {
332324
const { page_view_id } = this.props.tracking.getTrackingData();
333325

334-
return (
335-
<Ad pageViewId={page_view_id} />
336-
);
326+
return <Ad pageViewId={page_view_id} />;
337327
}
338-
339328
}
340329
```
341330
@@ -350,4 +339,3 @@ This library simply merges the tracking data objects together (as it flows throu
350339
### TypeScript Support
351340
352341
You can get the type definitions for React Tracking from DefinitelyTyped using `@types/react-tracking`. For an always up-to-date example of syntax, you should consult [the react-tracking type tests](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-tracking/test/react-tracking-with-types-tests.tsx).
353-

Diff for: package-lock.json

+18-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
],
5050
"homepage": "https://github.com/NYTimes/react-tracking",
5151
"dependencies": {
52-
"deepmerge": "^2.1.0",
53-
"hoist-non-react-statics": "^2.5.0"
52+
"deepmerge": "^2.1.1",
53+
"hoist-non-react-statics": "^3.0.1"
5454
},
5555
"peerDependencies": {
5656
"babel-runtime": "^6.20.0",

Diff for: src/trackEventMethodDecorator.js

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
/* eslint-disable prefer-rest-params */
21
import makeClassMemberDecorator from './makeClassMemberDecorator';
32

43
export default function trackEventMethodDecorator(trackingData = {}) {
54
return makeClassMemberDecorator(
65
decoratedFn =>
7-
function decorateClassMember() {
6+
function decorateClassMember(...args) {
87
const trackEvent = (...promiseArguments) => {
98
if (
109
this.props &&
@@ -13,18 +12,13 @@ export default function trackEventMethodDecorator(trackingData = {}) {
1312
) {
1413
const thisTrackingData =
1514
typeof trackingData === 'function'
16-
? trackingData(
17-
this.props,
18-
this.state,
19-
arguments,
20-
promiseArguments
21-
)
15+
? trackingData(this.props, this.state, args, promiseArguments)
2216
: trackingData;
2317
this.props.tracking.trackEvent(thisTrackingData);
2418
}
2519
};
2620

27-
const fn = Reflect.apply(decoratedFn, this, arguments);
21+
const fn = Reflect.apply(decoratedFn, this, args);
2822
if (Promise && Promise.resolve(fn) === fn) {
2923
return fn.then(trackEvent.bind(this)).catch(error => {
3024
trackEvent(null, error);

0 commit comments

Comments
 (0)