-
Notifications
You must be signed in to change notification settings - Fork 48
/
HoC.js
83 lines (73 loc) · 2.55 KB
/
HoC.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import React from 'react';
import {ensure} from './util';
import {update, unmount} from './Mixin';
// Mixin for RethinkDB query subscription support in React components. You'll
// generally want to use DefaultHoC or PropsHoC, which use BaseHoC to
// create more usable versions.
//
// In your component, you should define an observe(props, state) function that
// returns an object mapping query names to QueryRequests. See
// QueryRequest.js for the API.
//
// In the child component, you will have access to this.props.data, which is an
// object mapping from the same query names returned in observe() to the
// results of each query as an QueryResult. See QueryResult.js for the
// API.
//
// Here is a simple example of the mixin API:
// const observe = (props, state) => ({
// turtles: new QueryRequest({
// query: r.table('turtles'),
// changes: true,
// initial: [],
// }),
// });
// class App extends Component {
// render() {
// return <div>
// {this.props.data.turtles.value().map(function(x) {
// return <div key={x.id}>{x.firstName}</div>;
// })};
// </div>;
// },
// };
// BaseHoC(new Session())(observe)(App);
export const BaseHoC = sessionGetter => observe => ChildComponent => class ReactRethinkDB extends React.Component {
constructor(props, state) {
super();
this.observe = observe;
}
componentWillMount() {
const session = sessionGetter(this);
this.dispatch = session.runQuery.bind(session);
ensure(session && session._subscriptionManager,
`Must define Session`);
ensure(this.observe, `Must define observe()`);
ensure(session._connPromise, `Must connect() before mounting react-rethinkdb`);
this._rethinkMixinState = {session, subscriptions: {}};
this.data = this.data || {};
update(this, this.props, this.state);
}
componentDidMount() {
this._rethinkMixinState.isMounted = true;
}
componentWillUnmount() {
unmount(this);
this._rethinkMixinState.isMounted = false;
}
componentWillUpdate(nextProps, nextState) {
if (nextProps !== this.props || nextState !== this.state) {
update(this, nextProps, nextState);
}
}
render() {
return <ChildComponent data={this.data} dispatch={this.dispatch} {...this.props} />;
}
};
// HoC that uses rethink session from props. For example:
// class MyComponent extends Component {
// ...
// });
// var session = new Session();
// React.render(<MyComponent rethinkSession={session} />, mountNode);
export const PropsHoC = name => BaseHoC(component => component.props[name]);