@@ -48,12 +48,13 @@ Include `reactReduxFirebase` (store enhancer) and `firebaseReducer` (reducer) w
48
48
import React from ' react'
49
49
import { render } from ' react-dom'
50
50
import { Provider } from ' react-redux'
51
- import { createStore , combineReducers , compose } from ' redux'
52
- import { reactReduxFirebase , firebaseReducer } from ' react-redux-firebase'
53
- import firebase from ' firebase'
54
- // import { reduxFirestore, firestoreReducer } from 'redux-firestore' // <- needed if using firestore
51
+ import firebase from ' firebase/app'
52
+ import ' firebase/auth'
55
53
// import 'firebase/firestore' // <- needed if using firestore
56
54
// import 'firebase/functions' // <- needed if using httpsCallable
55
+ import { createStore , combineReducers , compose } from ' redux'
56
+ import { ReactReduxFirebaseProvider , firebaseReducer } from ' react-redux-firebase'
57
+ // import { createFirestoreInstance, firestoreReducer } from 'redux-firestore' // <- needed if using firestore
57
58
58
59
const firebaseConfig = {}
59
60
@@ -70,12 +71,6 @@ firebase.initializeApp(firebaseConfig)
70
71
// firebase.firestore() // <- needed if using firestore
71
72
// firebase.functions() // <- needed if using httpsCallable
72
73
73
- // Add reactReduxFirebase enhancer when making store creator
74
- const createStoreWithFirebase = compose (
75
- reactReduxFirebase (firebase, rrfConfig), // firebase instance as first argument
76
- // reduxFirestore(firebase) // <- needed if using firestore
77
- )(createStore)
78
-
79
74
// Add firebase to reducers
80
75
const rootReducer = combineReducers ({
81
76
firebase: firebaseReducer,
@@ -84,12 +79,21 @@ const rootReducer = combineReducers({
84
79
85
80
// Create store with reducers and initial state
86
81
const initialState = {}
87
- const store = createStoreWithFirebase (rootReducer, initialState)
82
+ const store = createStore (rootReducer, initialState)
83
+
84
+ const rrfProps = {
85
+ firebase,
86
+ config: rrfConfig,
87
+ dispatch: store .dispatch ,
88
+ // createFirestoreInstance // <- needed if using firestore
89
+ }
88
90
89
91
// Setup react-redux so that connect HOC can be used
90
92
const App = () => (
91
93
< Provider store= {store}>
92
- < Todos / >
94
+ < ReactReduxFirebaseProvider {... rrfProps}>
95
+ < Todos / >
96
+ < / ReactReduxFirebaseProvider>
93
97
< / Provider>
94
98
);
95
99
@@ -104,26 +108,30 @@ The Firebase instance can then be grabbed from context within your components (`
104
108
import React from ' react'
105
109
import PropTypes from ' prop-types'
106
110
import { withFirebase } from ' react-redux-firebase'
111
+ import { compose , withHandlers } from ' recompose'
107
112
108
- const Todos = ({ firebase }) => {
109
- const sampleTodo = { text: ' Sample' , done: false }
110
- const pushSample = () => firebase .push (' todos' , sampleTodo)
113
+ function Todos ({ firebase, addSampleTodo }) {
111
114
return (
112
115
< div>
113
- < h1> Todos< / h1>
114
- < ul>
115
- {todosList}
116
- < / ul>
117
- < input type= " text" ref= " newTodo" / >
118
- < button onClick= {pushSample}>
116
+ < h1> New Sample Todo< / h1>
117
+ < button onClick= {addSampleTodo}>
119
118
Add
120
119
< / button>
121
120
< / div>
122
121
)
123
122
}
124
123
125
- export default withFirebase (Todos)
126
- // or firebaseConnect()(Todos)
124
+ const enhance = compose (
125
+ withFirebase,
126
+ withHandlers ({
127
+ addSampleTodo : props => () => {
128
+ const sampleTodo = { text: ' Sample' , done: false }
129
+ return props .firebase .push (' todos' , sampleTodo)
130
+ }
131
+ })
132
+ )
133
+
134
+ export default enhance (Todos)
127
135
```
128
136
129
137
** Load Data (listeners automatically managed on mount/unmount)**
@@ -135,33 +143,30 @@ import { connect } from 'react-redux'
135
143
import { compose } from ' redux'
136
144
import { firebaseConnect , isLoaded , isEmpty } from ' react-redux-firebase'
137
145
138
- const Todos = ({ todos, firebase }) => {
139
- // Build Todos list if todos exist and are loaded
140
- const todosList = ! isLoaded (todos)
141
- ? ' Loading'
142
- : isEmpty (todos)
143
- ? ' Todo list is empty'
144
- : Object .keys (todos).map (
145
- (key , id ) => (
146
- < TodoItem key= {key} id= {id} todo= {todos[key]}/ >
147
- )
148
- )
146
+ function Todos ({ todos, firebase }) {
147
+ if (! isLoaded (todos)) {
148
+ return < div> Loading... < / div>
149
+ }
150
+ if (isEmpty (todos)) {
151
+ return < div> Todos List Is Empty< / div>
152
+ }
149
153
return (
150
154
< div>
151
- < h1> Todos< / h1>
152
155
< ul>
153
- {todosList}
156
+ {
157
+ Object .keys (todos).map (
158
+ (key , id ) => (
159
+ < TodoItem key= {key} id= {id} todo= {todos[key]}/ >
160
+ )
161
+ )
162
+ }
154
163
< / ul>
155
- < input type= " text" ref= " newTodo" / >
156
- < button onClick= {this .handleAdd }>
157
- Add
158
- < / button>
159
164
< / div>
160
165
)
161
166
}
162
167
163
168
export default compose (
164
- firebaseConnect ([
169
+ firebaseConnect (() => [
165
170
' todos' // { path: '/todos' } // object notation
166
171
]),
167
172
connect ((state ) => ({
@@ -179,8 +184,8 @@ It is common to make a detail page that loads a single item instead of a whole l
179
184
import React from ' react'
180
185
import PropTypes from ' prop-types'
181
186
import { connect } from ' react-redux'
182
- import { compose } from ' redux'
183
187
import { firebaseConnect , getVal } from ' react-redux-firebase'
188
+ import { compose , withHandlers } from ' recompose'
184
189
185
190
// Component enhancer that loads todo into redux then into the todo prop
186
191
const enhance = compose (
@@ -193,21 +198,27 @@ const enhance = compose(
193
198
}),
194
199
connect (({ firebase }, props ) => ({
195
200
todo: getVal (firebase, ` data/todos/${ props .params .todoId } ` ), // lodash's get can also be used
196
- }))
201
+ })),
202
+ withHandlers ({
203
+ updateTodo : props => () => {
204
+ return firebase .update (` todos/${ params .todoId } ` , { done: ! todo .isDone })
205
+ }
206
+ })
197
207
)
198
208
199
- const Todo = ({ todo, firebase, params }) =>
200
- < div>
201
- < input
202
- name= " isDone"
203
- type= " checkbox"
204
- checked= {todo .isDone }
205
- onChange= {() =>
206
- firebase .update (` todos/${ params .todoId } ` , { done: ! todo .isDone })
207
- }
208
- / >
209
- < span> {todo .label }< / span>
210
- < / div>
209
+ function Todo ({ todo }) {
210
+ return (
211
+ < div>
212
+ < input
213
+ name= " isDone"
214
+ type= " checkbox"
215
+ checked= {todo .isDone }
216
+ onChange= {updateTodo}
217
+ / >
218
+ < span> {todo .label }< / span>
219
+ < / div>
220
+ )
221
+ }
211
222
212
223
// Export enhanced component
213
224
export default enhance (Todo)
@@ -223,21 +234,38 @@ import { connect } from 'react-redux'
223
234
import { compose } from ' redux'
224
235
import { withFirebase , isLoaded , isEmpty } from ' react-redux-firebase'
225
236
226
- const Todos = ({ firebase }) => {
227
- // Build Todos list if todos exist and are loaded
228
- const todosList = ! isLoaded (todos)
229
- ? ' Loading'
230
- : isEmpty (todos)
231
- ? ' Todo list is empty'
232
- : Object .keys (todos).map (
233
- (key , id ) => < TodoItem key= {key} id= {id} todo= {todos[key]}/ >
237
+ function TodosList ({ todos }) {
238
+ if (! isLoaded (todos)) {
239
+ return < div> Loading... < / div>
240
+ }
241
+ if (isEmpty (todos)) {
242
+ return < div> Todos List Is Empty< / div>
243
+ }
244
+ return (
245
+ < ul>
246
+ {
247
+ Object .keys (todos).map ((key , id ) =>
248
+ < TodoItem key= {key} id= {id} todo= {todos[key]}/ >
234
249
)
250
+ }
251
+ < / ul>
252
+ )
253
+ }
254
+ const withTodosData = compose (
255
+ withFirebase, // or firebaseConnect()
256
+ connect ((state ) => ({
257
+ todos: state .firebase .data .todos ,
258
+ // profile: state.firebase.profile // load profile
259
+ }))
260
+ )
261
+
262
+ const EnhancedTodosList = withTodosData (TodosList)
263
+
264
+ function Todos ({ firebase }) {
235
265
return (
236
266
< div>
237
267
< h1> Todos< / h1>
238
- < ul>
239
- {todosList}
240
- < / ul>
268
+ < EnhancedTodosList / >
241
269
< button onClick= {() => firebase .watchEvent (' value' , ' todos' )}>
242
270
Load Todos
243
271
< / button>
@@ -246,13 +274,7 @@ const Todos = ({ firebase }) => {
246
274
}
247
275
248
276
// Export enhanced component
249
- export default compose (
250
- withFirebase, // or firebaseConnect()
251
- connect ((state ) => ({
252
- todos: state .firebase .data .todos ,
253
- // profile: state.firebase.profile // load profile
254
- }))
255
- )(Todos)
277
+ export default withFirebase (Todos)
256
278
```
257
279
258
280
## Firestore
@@ -336,13 +358,15 @@ Please visit the [FAQ section of the docs](http://docs.react-redux-firebase.com/
336
358
337
359
Most commonly people consume Redux Firestore as a [ CommonJS module] ( http://webpack.github.io/docs/commonjs.html ) . This module is what you get when you import redux in a Webpack, Browserify, or a Node environment.
338
360
339
- If you don't use a module bundler, it's also fine. The redux-firestore npm package includes precompiled production and development [ UMD builds] ( https://github.com/umdjs/umd ) in the [ dist folder] ( https://unpkg.com/redux-firestore@latest/dist/ ) . They can be used directly without a bundler and are thus compatible with many popular JavaScript module loaders and environments. For example, you can drop a UMD build as a ` <script> ` tag on the page. The UMD builds make Redux Firestore available as a ` window.ReduxFirestore ` global variable.
361
+ If you don't use a module bundler, it's also fine. The redux-firestore npm package includes precompiled production and development [ UMD builds] ( https://github.com/umdjs/umd ) in the [ dist folder] ( https://unpkg.com/redux-firestore@latest/dist/ ) . They can be used directly without a bundler and are thus compatible with many popular JavaScript module loaders and environments. For example, you can drop a UMD build as a ` <script> ` tag on the page. The UMD builds make Redux Firestore available as a ` window.ReactReduxFirebase ` global variable.
340
362
341
363
It can be imported like so:
342
364
343
365
``` html
344
366
<script src =" ../node_modules/react-redux-firebase/dist/react-redux-firebase.min.js" ></script >
367
+ <script src =" ../node_modules/redux-firestore/dist/redux-firestore.min.js" ></script >
345
368
<!-- or through cdn: <script src="https://unpkg.com/react-redux-firebase@latest/dist/react-redux-firebase.min.js"></script> -->
369
+ <!-- or through cdn: <script src="https://unpkg.com/redux-firestore@latest/dist/redux-firestore.min.js"></script> -->
346
370
<script >console .log (' react redux firebase:' , window .ReactReduxFirebase ) </script >
347
371
```
348
372
@@ -365,8 +389,8 @@ Thank you to all our backers! 🙏
365
389
[ npm-downloads-image ] : https://img.shields.io/npm/dm/react-redux-firebase.svg?style=flat-square
366
390
[ quality-image ] : http://npm.packagequality.com/shield/react-redux-firebase.svg?style=flat-square
367
391
[ quality-url ] : https://packagequality.com/#?package=react-redux-firebase
368
- [ backers ] :https://opencollective.com/react-redux-firebase/backers/badge.svg?style=flat-square&color=blue
369
- [ become-a-backer ] :https://opencollective.com/react-redux-firebase#backer
392
+ [ backers ] : https://opencollective.com/react-redux-firebase/backers/badge.svg?style=flat-square&color=blue
393
+ [ become-a-backer ] : https://opencollective.com/react-redux-firebase#backer
370
394
[ travis-image ] : https://img.shields.io/travis/prescottprue/react-redux-firebase/master.svg?style=flat-square
371
395
[ travis-url ] : https://travis-ci.org/prescottprue/react-redux-firebase
372
396
[ daviddm-image ] : https://img.shields.io/david/prescottprue/react-redux-firebase.svg?style=flat-square
0 commit comments