Skip to content

Commit 71dee92

Browse files
authored
v3.0.0-alpha.3 (#595)
* fix(firestoreConnect): remove remaining usage of old context pattern - #594 * fix(HOCs): add displayName to `firebaseConnect` and `firestoreConnect`
1 parent 1e96425 commit 71dee92

12 files changed

+137
-105
lines changed

.babelrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"presets": [
3-
"minify",
3+
["minify", { "keepFnName": true }],
44
"@babel/preset-react",
55
["@babel/env", {
66
"targets": {

examples/complete/simple/src/Home.js

+42-38
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,50 @@ import TodoItem from './TodoItem'
1212
import './App.css'
1313
import NewTodo from './NewTodo';
1414

15-
const Home = ({ firebase, todos }) => (
16-
<div className='App'>
17-
<div className='App-header'>
18-
<h2>react-redux-firebase demo</h2>
19-
<img src={logo} className='App-logo' alt='logo' />
15+
function Home({ firebase, todos }) {
16+
return (
17+
<div className='App'>
18+
<div className='App-header'>
19+
<h2>react-redux-firebase demo</h2>
20+
<img src={logo} className='App-logo' alt='logo' />
21+
</div>
22+
<div className='App-todos'>
23+
<h4>
24+
Loaded From
25+
<span className='App-Url'>
26+
<a href='https://redux-firebasev3.firebaseio.com/'>
27+
redux-firebasev3.firebaseio.com
28+
</a>
29+
</span>
30+
</h4>
31+
<h4>Todos List</h4>
32+
{
33+
!isLoaded(todos)
34+
? 'Loading'
35+
: isEmpty(todos)
36+
? 'Todo list is empty'
37+
: todos.reverse().map(({ value: todo, key }, ind) => (
38+
<TodoItem
39+
key={`${key}-${ind}`}
40+
id={key}
41+
{...todo}
42+
/>
43+
))
44+
}
45+
<NewTodo />
46+
</div>
2047
</div>
21-
<div className='App-todos'>
22-
<h4>
23-
Loaded From
24-
<span className='App-Url'>
25-
<a href='https://redux-firebasev3.firebaseio.com/'>
26-
redux-firebasev3.firebaseio.com
27-
</a>
28-
</span>
29-
</h4>
30-
<h4>Todos List</h4>
31-
{
32-
!isLoaded(todos)
33-
? 'Loading'
34-
: isEmpty(todos)
35-
? 'Todo list is empty'
36-
: todos.reverse().map(({ value: todo, key }, ind) => (
37-
<TodoItem
38-
key={`${key}-${ind}`}
39-
id={key}
40-
{...todo}
41-
/>
42-
))
43-
}
44-
<NewTodo />
45-
</div>
46-
</div>
47-
)
48+
)
49+
}
4850

4951
Home.propTypes = {
50-
// firebase: PropTypes.object.isRequired
52+
firebase: PropTypes.object.isRequired
53+
}
54+
55+
function mapStateToProps(state) {
56+
return {
57+
todos: state.firebase.ordered.todos
58+
}
5159
}
5260

5361
const enhance = compose(
@@ -57,11 +65,7 @@ const enhance = compose(
5765
queryParams: ['limitToLast=10']
5866
}
5967
]),
60-
connect(
61-
({ firebase }) => ({
62-
todos: firebase.ordered.todos,
63-
})
64-
)
68+
connect(mapStateToProps)
6569
)
6670

6771
export default enhance(Home)

examples/complete/simple/src/TodoItem.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ const enhance = compose(
2121
})
2222
)
2323

24-
const TodoItem = (props) => {
24+
function TodoItem(props) {
2525
const { deleteTodo, toggleDone, text, name, done } = props
26-
console.log('props', props)
2726
return (
2827
<li className="Todo">
2928
<input

package-lock.json

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

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-redux-firebase",
3-
"version": "3.0.0-alpha.2",
3+
"version": "3.0.0-alpha.3",
44
"description": "Redux integration for Firebase. Comes with a Higher Order Components for use with React.",
55
"main": "lib/index.js",
66
"module": "es/index.js",

src/ReactReduxFirebaseProvider.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import createFirebaseInstance from './createFirebaseInstance'
44
import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'
55
import ReduxFirestoreProvider from './ReduxFirestoreProvider'
66

7-
const ReactReduxFirebaseProvider = (props = {}) => {
7+
function ReactReduxFirebaseProvider(props = {}) {
88
const {
99
children,
1010
config,

src/ReduxFirestoreProvider.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import PropTypes from 'prop-types'
33
import ReduxFirestoreContext from './ReduxFirestoreContext'
44

5-
const ReduxFirestoreProvider = (props = {}) => {
5+
function ReduxFirestoreProvider(props = {}) {
66
const {
77
children,
88
config,

src/firebaseConnect.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
33
import { isEqual, differenceWith } from 'lodash'
44
import hoistStatics from 'hoist-non-react-statics'
55
import { watchEvents, unWatchEvents } from './actions/query'
6-
import { getEventsFromInput, createCallable, getDisplayName } from './utils'
6+
import { getEventsFromInput, createCallable, wrapDisplayName } from './utils'
77
import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'
88

99
/**
@@ -28,14 +28,17 @@ export const createFirebaseConnect = (storeKey = 'store') => (
2828
dataOrFn = []
2929
) => WrappedComponent => {
3030
class FirebaseConnectWrapped extends Component {
31-
static displayName = `FirebaseConnect(${getDisplayName(WrappedComponent)})`
31+
static displayName = wrapDisplayName(
32+
WrappedComponent,
33+
'FirebaseConnectWrapped'
34+
)
3235
static wrappedComponent = WrappedComponent
3336

3437
firebaseEvents = []
3538
firebase = null
3639
prevData = null
3740

38-
componentWillMount() {
41+
componentDidMount() {
3942
const { firebase, dispatch } = this.props
4043

4144
// Allow function to be passed
@@ -87,7 +90,7 @@ export const createFirebaseConnect = (storeKey = 'store') => (
8790

8891
FirebaseConnectWrapped.propTypes = {
8992
dispatch: PropTypes.func.isRequired,
90-
firebase: PropTypes.object
93+
firebase: PropTypes.object.isRequired
9194
}
9295

9396
const HoistedComp = hoistStatics(FirebaseConnectWrapped, WrappedComponent)
@@ -104,9 +107,10 @@ export const createFirebaseConnect = (storeKey = 'store') => (
104107
</ReactReduxFirebaseContext.Consumer>
105108
)
106109

107-
FirebaseConnect.propTypes = {
108-
dispatch: PropTypes.func.isRequired
109-
}
110+
FirebaseConnect.displayName = wrapDisplayName(
111+
WrappedComponent,
112+
'FirebaseConnect'
113+
)
110114

111115
return FirebaseConnect
112116
}

src/firestoreConnect.js

+20-17
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ReduxFirestoreContext from './ReduxFirestoreContext'
1616
* Firebase state (state.firebase)
1717
* @return {Function} - HOC that accepts a watchArray and wraps a component
1818
* @example <caption>Basic</caption>
19-
* // this.props.firebase set on App component as firebase object with helpers
19+
* // props.firebase set on App component as firebase object with helpers
2020
* import { createFirestoreConnect } from 'react-redux-firebase'
2121
* // create firebase connect that uses another redux store
2222
* const firestoreConnect = createFirestoreConnect('anotherStore')
@@ -28,7 +28,10 @@ export const createFirestoreConnect = (storeKey = 'store') => (
2828
) => WrappedComponent => {
2929
class FirestoreConnectWrapped extends Component {
3030
static wrappedComponent = WrappedComponent
31-
static displayName = wrapDisplayName(WrappedComponent, 'FirestoreConnect')
31+
static displayName = wrapDisplayName(
32+
WrappedComponent,
33+
'FirestoreConnectWrapped'
34+
)
3235

3336
prevData = null
3437

@@ -37,20 +40,18 @@ export const createFirestoreConnect = (storeKey = 'store') => (
3740
}
3841

3942
componentDidMount() {
40-
const { firestore } = this.store
4143
if (this.firestoreIsEnabled) {
42-
// Allow function to be passed
44+
// Listener configs as object (handling function being passed)
4345
const inputAsFunc = createCallable(dataOrFn)
4446
this.prevData = inputAsFunc(this.props, this.props)
45-
46-
firestore.setListeners(this.prevData)
47+
// Attach listeners based on listener config
48+
this.props.firestore.setListeners(this.prevData)
4749
}
4850
}
4951

50-
componentDidUnmount() {
51-
const { firestore } = this.store
52+
componentWillUnmount() {
5253
if (this.firestoreIsEnabled && this.prevData) {
53-
firestore.unsetListeners(this.prevData)
54+
this.props.firestore.unsetListeners(this.prevData)
5455
}
5556
}
5657

@@ -59,7 +60,7 @@ export const createFirestoreConnect = (storeKey = 'store') => (
5960
const inputAsFunc = createCallable(dataOrFn)
6061
const data = inputAsFunc(np, this.props)
6162

62-
// Handle changes to data
63+
// Check for changes in the listener configs
6364
if (this.firestoreIsEnabled && !isEqual(data, this.prevData)) {
6465
const changes = this.getChanges(data, this.prevData)
6566

@@ -86,7 +87,7 @@ export const createFirestoreConnect = (storeKey = 'store') => (
8687
}
8788

8889
FirestoreConnectWrapped.propTypes = {
89-
dispatch: PropTypes.func.isRequired,
90+
dispatch: PropTypes.func,
9091
firebase: PropTypes.object,
9192
firestore: PropTypes.object
9293
}
@@ -98,6 +99,10 @@ export const createFirestoreConnect = (storeKey = 'store') => (
9899
{firestore => <HoistedComp firestore={firestore} {...props} />}
99100
</ReduxFirestoreContext.Consumer>
100101
)
102+
FirestoreConnect.displayName = wrapDisplayName(
103+
WrappedComponent,
104+
'FirestoreConnect'
105+
)
101106

102107
FirestoreConnect.propTypes = {
103108
dispatch: PropTypes.func.isRequired
@@ -118,20 +123,18 @@ export const createFirestoreConnect = (storeKey = 'store') => (
118123
* is passed the current props and the firebase object.
119124
* @return {Function} - that accepts a component to wrap and returns the wrapped component
120125
* @example <caption>Basic</caption>
121-
* // this.props.firebase set on App component as firebase object with helpers
126+
* // props.firebase set on App component as firebase object with helpers
122127
* import { firestoreConnect } from 'react-redux-firebase'
123128
* export default firestoreConnect()(SomeComponent)
124129
* @example <caption>Basic</caption>
125130
* import { connect } from 'react-redux'
126131
* import { firestoreConnect } from 'react-redux-firebase'
127132
*
128-
* // pass todos list from redux as this.props.todosList
133+
* // pass todos list from redux as props.todosList
129134
* export default compose(
130-
* firestoreConnect(['todos']), // sync todos collection from Firestore into redux
135+
* firestoreConnect(() => ['todos']), // sync todos collection from Firestore into redux
131136
* connect((state) => ({
132-
* todosList: state.firestore.data.todos,
133-
* profile: state.firestore.profile, // pass profile data as this.props.profile
134-
* auth: state.firestore.auth // pass auth data as this.props.auth
137+
* todosList: state.firestore.data.todos
135138
* })
136139
* )(SomeComponent)
137140
*/

src/utils/index.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function createCallable(f) {
1010
return isFunction(f) ? f : () => f
1111
}
1212

13-
export function getDisplayName(Component) {
13+
function getDisplayName(Component) {
1414
if (typeof Component === 'string') {
1515
return Component
1616
}
@@ -22,6 +22,11 @@ export function getDisplayName(Component) {
2222
return Component.displayName || Component.name || 'Component'
2323
}
2424

25+
/**
26+
* Get provided react component's display name and wrap with with a passed name.
27+
* @param {React.Component} BaseComponent - Component from which to get name to wrap
28+
* @param {String} hocName - Name of wrapping hoc
29+
*/
2530
export function wrapDisplayName(BaseComponent, hocName) {
2631
return `${hocName}(${getDisplayName(BaseComponent)})`
2732
}

src/withFirebase.js

+23-15
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'
1515
* @return {Function} - Higher Order Component which accepts an array of
1616
* watchers config and wraps a React Component
1717
* @example <caption>Basic</caption>
18-
* // this.props.firebase set on App component as firebase object with helpers
18+
* // props.firebase set on App component as firebase object with helpers
1919
* import { createWithFirebase } from 'react-redux-firebase'
2020
*
2121
* // create withFirebase that uses another redux store
@@ -68,28 +68,34 @@ export const createWithFirebase = (storeKey = 'store') => WrappedComponent => {
6868
* @example <caption>Basic</caption>
6969
* import { withFirebase } from 'react-redux-firebase'
7070
*
71-
* const AddData = ({ firebase: { push } }) =>
72-
* <div>
73-
* <button onClick={() => push('todos', { done: false, text: 'Sample' })}>
74-
* Add Sample Todo
75-
* </button>
76-
* </div>
71+
* function AddData({ firebase: { push } }) {
72+
* return (
73+
* <div>
74+
* <button onClick={() => push('todos', { done: false, text: 'Sample' })}>
75+
* Add Sample Todo
76+
* </button>
77+
* </div>
78+
* )
79+
* }
7780
*
7881
* export default withFirebase(AddData)
7982
* @example <caption>Within HOC Composition</caption>
8083
* import { compose } from 'redux' // can also come from recompose
8184
* import { withHandlers } from 'recompose'
8285
* import { withFirebase } from 'react-redux-firebase'
8386
*
84-
* const AddTodo = ({ addTodo }) =>
85-
* <div>
86-
* <button onClick={addTodo}>
87-
* Add Sample Todo
88-
* </button>
89-
* </div>
87+
* function AddTodo({ addTodo }) {
88+
* return (
89+
* <div>
90+
* <button onClick={addTodo}>
91+
* Add Sample Todo
92+
* </button>
93+
* </div>
94+
* )
95+
* }
9096
*
91-
* export default compose(
92-
* withFirebase(AddTodo),
97+
* const enhance = compose(
98+
* withFirebase,
9399
* withHandlers({
94100
* addTodo: props => () =>
95101
* props.firestore.add(
@@ -98,5 +104,7 @@ export const createWithFirebase = (storeKey = 'store') => WrappedComponent => {
98104
* )
99105
* })
100106
* )
107+
*
108+
* export default enhance(AddTodo)
101109
*/
102110
export default createWithFirebase()

0 commit comments

Comments
 (0)