diff --git a/package.json b/package.json
index 859a29b..f61f5f3 100644
--- a/package.json
+++ b/package.json
@@ -25,5 +25,8 @@
"babel-eslint": "^4.1.7",
"eslint": "^0.22.1",
"mocha": "^2.2.5"
+ },
+ "peerDependencies": {
+ "react": "^0.14.0 || ^15.0.0"
}
}
diff --git a/src/HoC.js b/src/HoC.js
new file mode 100644
index 0000000..bfb5ef0
--- /dev/null
+++ b/src/HoC.js
@@ -0,0 +1,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
+// {this.props.data.turtles.value().map(function(x) {
+// return
{x.firstName}
;
+// })};
+//
;
+// },
+// };
+
+// 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 ;
+ }
+};
+
+// HoC that uses rethink session from props. For example:
+// class MyComponent extends Component {
+// ...
+// });
+// var session = new Session();
+// React.render(, mountNode);
+export const PropsHoC = name => BaseHoC(component => component.props[name]);
diff --git a/src/Mixin.js b/src/Mixin.js
index d22258d..9af5a47 100644
--- a/src/Mixin.js
+++ b/src/Mixin.js
@@ -1,7 +1,7 @@
import {QueryResult} from './QueryResult';
import {ensure} from './util';
-const update = (component, props, state) => {
+export const update = (component, props, state) => {
const observed = component.observe(props, state);
const {session, subscriptions} = component._rethinkMixinState;
const subscriptionManager = session._subscriptionManager;
@@ -27,7 +27,7 @@ const update = (component, props, state) => {
});
};
-const unmount = component => {
+export const unmount = component => {
const {subscriptions} = component._rethinkMixinState;
Object.keys(subscriptions).forEach(key => {
subscriptions[key].unsubscribe();
diff --git a/src/index.js b/src/index.js
index fd62243..c460a04 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,4 @@
+import {BaseHoC, PropsHoC} from './HoC';
import {BaseMixin, PropsMixin} from './Mixin';
import {QueryRequest} from './QueryRequest';
import {MetaSession} from './Session';
@@ -12,24 +13,31 @@ const DefaultSession = new Session();
// Singleton mixin for convenience, which uses the DefaultSession singleton as
// the session.
const DefaultMixin = BaseMixin(() => DefaultSession);
+const DefaultHoC = BaseHoC(() => DefaultSession);
const ReactRethinkdb = {
BaseMixin,
PropsMixin,
+ BaseHoC,
+ PropsHoC,
QueryRequest,
r,
Session,
DefaultSession,
- DefaultMixin
+ DefaultMixin,
+ DefaultHoC
};
export {
BaseMixin,
PropsMixin,
+ BaseHoC,
+ PropsHoC,
QueryRequest,
r,
Session,
DefaultSession,
DefaultMixin,
+ DefaultHoC,
ReactRethinkdb as default,
};