Skip to content

Commit d322124

Browse files
committed
Merge branch 'next' into v3.0.0-alpha.7
2 parents 20956d3 + 8b3b7f9 commit d322124

File tree

2 files changed

+74
-26
lines changed

2 files changed

+74
-26
lines changed

src/firebaseConnect.js

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { watchEvents, unWatchEvents } from './actions/query'
66
import { getEventsFromInput, createCallable, wrapDisplayName } from './utils'
77
import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'
88

9+
// Reserved props that should not be passed into a firebaseConnect wrapped
10+
// component. Will throw an error if they are.
11+
const RESERVED_PROPS = ['_firebaseRef', '_dispatch']
12+
913
/**
1014
* @name createFirebaseConnect
1115
* @description Function that creates a Higher Order Component that
@@ -39,27 +43,27 @@ export const createFirebaseConnect = (storeKey = 'store') => (
3943
prevData = null
4044

4145
componentDidMount() {
42-
const { firebase, dispatch } = this.props
46+
const { _firebaseRef, _dispatch } = this.props
4347

4448
// Allow function to be passed
4549
const inputAsFunc = createCallable(dataOrFn)
4650
this.prevData = inputAsFunc(this.props, this.props)
4751

48-
const { ref, helpers, storage, database, auth } = firebase
52+
const { ref, helpers, storage, database, auth } = _firebaseRef
4953
this.firebase = { ref, storage, database, auth, ...helpers }
5054

5155
this._firebaseEvents = getEventsFromInput(this.prevData)
5256

53-
watchEvents(firebase, dispatch, this._firebaseEvents)
57+
watchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
5458
}
5559

5660
componentWillUnmount() {
57-
const { firebase, dispatch } = this.props
58-
unWatchEvents(firebase, dispatch, this._firebaseEvents)
61+
const { _firebaseRef, _dispatch } = this.props
62+
unWatchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
5963
}
6064

6165
componentWillReceiveProps(np) {
62-
const { firebase, dispatch } = this.props
66+
const { _firebaseRef, _dispatch } = this.props
6367
const inputAsFunc = createCallable(dataOrFn)
6468
const data = inputAsFunc(np, this.store)
6569

@@ -71,41 +75,70 @@ export const createFirebaseConnect = (storeKey = 'store') => (
7175
this.prevData = data
7276
// UnWatch all current events
7377
unWatchEvents(
74-
firebase,
75-
dispatch,
78+
_firebaseRef,
79+
_dispatch,
7680
getEventsFromInput(itemsToUnsubscribe)
7781
)
7882
// Get watch events from new data
7983
this._firebaseEvents = getEventsFromInput(data)
8084

8185
// Watch new events
82-
watchEvents(firebase, dispatch, getEventsFromInput(itemsToSubscribe))
86+
watchEvents(
87+
_firebaseRef,
88+
_dispatch,
89+
getEventsFromInput(itemsToSubscribe)
90+
)
8391
}
8492
}
8593

8694
render() {
87-
return <WrappedComponent {...this.props} />
95+
// Prevent reserved props from being passed down to children
96+
let props = Object.keys(this.props).reduce((acc, p) => {
97+
if (RESERVED_PROPS.indexOf(p) === -1) {
98+
acc[p] = this.props[p]
99+
}
100+
return acc
101+
}, {})
102+
103+
return <WrappedComponent {...props} />
88104
}
89105
}
90106

91107
FirebaseConnectWrapped.propTypes = {
92-
dispatch: PropTypes.func.isRequired,
93-
firebase: PropTypes.object.isRequired
108+
_dispatch: PropTypes.func.isRequired,
109+
_firebaseRef: PropTypes.object.isRequired
94110
}
95111

96112
const HoistedComp = hoistStatics(FirebaseConnectWrapped, WrappedComponent)
97113

98-
const FirebaseConnect = props => (
99-
<ReactReduxFirebaseContext.Consumer>
100-
{firebase => (
101-
<HoistedComp
102-
firebase={firebase}
103-
dispatch={firebase.dispatch}
104-
{...props}
105-
/>
106-
)}
107-
</ReactReduxFirebaseContext.Consumer>
108-
)
114+
const FirebaseConnect = props => {
115+
// Check that reserved props are not supplied to a FirebaseConnected
116+
// component and if they are, throw an error so the developer can rectify
117+
// this issue.
118+
const clashes = Object.keys(props).filter(
119+
k => !!RESERVED_PROPS.find(r => r === k)
120+
)
121+
122+
if (clashes.length > 0) {
123+
throw new Error(
124+
`Supplied prop/s "${clashes.join(
125+
'", "'
126+
)}" are reserved for internal firebaseConnect() usage.`
127+
)
128+
}
129+
130+
return (
131+
<ReactReduxFirebaseContext.Consumer>
132+
{_firebaseRef => (
133+
<HoistedComp
134+
_firebaseRef={_firebaseRef}
135+
_dispatch={_firebaseRef.dispatch}
136+
{...props}
137+
/>
138+
)}
139+
</ReactReduxFirebaseContext.Consumer>
140+
)
141+
}
109142

110143
FirebaseConnect.displayName = wrapDisplayName(
111144
WrappedComponent,

test/unit/firebaseConnect.spec.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const getFirebaseWatchers = store => {
2020
return { ...store.firebase._.watchers }
2121
}
2222

23-
const createContainer = () => {
23+
const createContainer = additionalWrappedProps => {
2424
const store = storeWithFirebase()
2525
const WrappedContainer = firebaseConnect(props => {
2626
const itemsToSubscribe =
@@ -33,12 +33,12 @@ const createContainer = () => {
3333

3434
const tree = TestUtils.renderIntoDocument(
3535
<ProviderMock store={store}>
36-
<WrappedContainer pass="through" />
36+
<WrappedContainer pass="through" {...additionalWrappedProps} />
3737
</ProviderMock>
3838
)
3939

4040
return {
41-
container: TestUtils.findRenderedComponentWithType(tree, WrappedContainer),
41+
// container: TestUtils.findRenderedComponentWithType(tree, WrappedContainer),
4242
parent: TestUtils.findRenderedComponentWithType(tree, ProviderMock),
4343
store
4444
}
@@ -106,6 +106,21 @@ describe('firebaseConnect', () => {
106106
expect(values(getFirebaseWatchers(store))).to.eql([1])
107107
})
108108

109+
it('throws an exception if passed a prop that clashes with a reserved param', () => {
110+
let exceptions = []
111+
112+
try {
113+
createContainer({
114+
_firebaseRef: '__SECRET_INTERNALS',
115+
_dispatch: '__SECRET_INTERNALS'
116+
})
117+
} catch (e) {
118+
exceptions.push(e)
119+
}
120+
121+
expect(exceptions.length).to.equal(1)
122+
})
123+
109124
describe.skip('sets displayName static as ', () => {
110125
/* eslint-disable no-template-curly-in-string */
111126
describe('FirebaseConnect(${WrappedComponentName}) for', () => {

0 commit comments

Comments
 (0)