|
1 | 1 | React Firebase |
2 | 2 | ============== |
3 | 3 |
|
4 | | -React bindings for [Firebase](https://www.firebase.com). |
| 4 | +React bindings for [Firebase](https://firebase.google.com). |
5 | 5 |
|
6 | 6 | ## Installation |
7 | 7 |
|
8 | | -React Firebase requires **React 0.14 or later.** |
9 | | - |
10 | 8 | ``` |
11 | 9 | npm install --save react-firebase |
12 | 10 | ``` |
13 | 11 |
|
14 | | -## Usage |
15 | | - |
16 | | -### `<Provider firebase>` |
| 12 | +React Firebase requires **[React 0.14](https://github.com/facebook/react) and [Firebase 3](https://www.npmjs.com/package/firebase) or later.** |
17 | 13 |
|
18 | | -Makes a Firebase refence available to the `connect()` calls in the component hierarchy below. Normally, you can’t use `connect()` without wrapping the root component in `<Provider>`. |
19 | | - |
20 | | -If you *really* need to, you can manually pass `firebase` as a prop to every `connect()`ed component, but we only recommend to do this for stubbing `firebase` in unit tests, or in non-fully-React codebases. Normally, you should just use `<Provider>`. |
21 | | - |
22 | | -#### Props |
23 | | - |
24 | | -* `firebase` (*[Firebase](https://www.firebase.com/docs/web/api/firebase/constructor.html)*): A Firebase reference. |
25 | | -* `children` (*ReactElement*) The root of your component hierarchy. |
26 | | - |
27 | | -#### Example |
28 | | - |
29 | | -##### Vanilla React |
| 14 | +## Example |
30 | 15 |
|
31 | 16 | ```js |
32 | | -const firebase = new Firebase('https://my-firebase.firebaseio.com'); |
33 | | - |
34 | | -ReactDOM.render( |
35 | | - <Provider firebase={firebase}> |
36 | | - <MyRootComponent /> |
37 | | - </Provider>, |
38 | | - rootEl |
| 17 | +import React from 'react' |
| 18 | +import firebase from 'firebase' |
| 19 | +import { connect } from 'react-firebase' |
| 20 | + |
| 21 | +firebase.initializeApp({ |
| 22 | + databaseURL: 'https://react-firebase-sandbox.firebaseio.com' |
| 23 | +}) |
| 24 | + |
| 25 | +const Counter = ({ value, setValue }) => ( |
| 26 | + <div> |
| 27 | + <button onClick={() => setCount(value - 1)}>-</button> |
| 28 | + <span>{value}</span> |
| 29 | + <button onClick={() => setCount(value + 1)}>+</button> |
| 30 | + </div> |
39 | 31 | ) |
40 | | -``` |
41 | | - |
42 | | -### `connect([mapPropsToSubscriptions], [mapFirebaseToProps], [mergeProps], [options])` |
43 | 32 |
|
44 | | -Connects a React component to a Firebase refence. |
| 33 | +export default connect((props, ref) => ({ |
| 34 | + value: 'counterValue', |
| 35 | + setValue: value => ref('counterValue').set(value) |
| 36 | +}))(TodosApp) |
| 37 | +``` |
45 | 38 |
|
46 | | -It does not modify the component class passed to it. |
47 | | -Instead, it *returns* a new, connected component class, for you to use. |
| 39 | +## Usage |
48 | 40 |
|
49 | | -#### Arguments |
| 41 | +### `connect([mapFirebaseToProps])` |
50 | 42 |
|
51 | | -* [`mapPropsToSubscriptions(props): subscriptions`] \(*Function*): If specified, the component will subscribe to Firebase `change` events. Its result must be a plain object, and it will be merged into the component’s props. Each value must either a path to a location in the firebase or a function with the signature `createQuery(firebase): [Query](https://www.firebase.com/docs/web/api/query)`. |
| 43 | +Connects a React component to a Firebase App reference. |
52 | 44 |
|
53 | | -* [`mapFirebaseToProps(firebase, [ownProps]): actionProps`] \(*Function*): If specified, its result must be a plain object where each value is assumed to be a function that performs modifications to the Firebase. If you omit it, the default implementation just injects `firebase` into your component’s props. |
| 45 | +It does not modify the component class passed to it. Instead, it *returns* a new, connected component class, for you to use. |
54 | 46 |
|
55 | | -* [`mergeProps(stateProps, actionProps, ownProps): props`] \(*Function*): If specified, it is passed the result of `mapPropsToSubscriptions()`, `mapFirebaseToProps()`, and the parent `props`. The plain object you return from it will be passed as props to the wrapped component. You may specify this function to select a slice of the state based on props, or to bind action creators to a particular variable from props. If you omit it, `Object.assign({}, ownProps, stateProps, actionProps)` is used by default. |
| 47 | +#### Arguments |
56 | 48 |
|
57 | | -* [`options`] *(Object)* If specified, further customizes the behavior of the connector. |
58 | | - * [`pure = true`] *(Boolean)*: If true, implements `shouldComponentUpdate` and shallowly compares the result of `mergeProps`, preventing unnecessary updates, assuming that the component is a “pure” component and does not rely on any input or state other than its props and subscriptions. *Defaults to `true`.* |
| 49 | +* [`mapFirebaseToProps(props, ref, firebaseApp): subscriptions`] \(*Object or Function*): Its result, or the argument itself must be a plain object. Each value must either be a path to a location in your database, a query object or a function. If you omit it, the default implementation just passes `firebaseApp` as a prop to your component. |
59 | 50 |
|
60 | 51 | #### Returns |
61 | 52 |
|
62 | | -A React component class that injects subscriptions and actions into your component according to the specified options. |
| 53 | +A React component class that passes subscriptions and actions as props to your component according to the specified options. |
63 | 54 |
|
64 | 55 | ##### Static Properties |
65 | 56 |
|
66 | 57 | * `WrappedComponent` *(Component)*: The original component class passed to `connect()`. |
67 | 58 |
|
68 | | -#### Remarks |
69 | | - |
70 | | -* It needs to be invoked two times. The first time with its arguments described above, and a second time, with the component: `connect(mapPropsToSubscriptions, mapFirebaseToProps, mergeProps)(MyComponent)`. |
71 | | - |
72 | | -* It does not modify the passed React component. It returns a new, connected component, that you should use instead. |
73 | | - |
74 | 59 | #### Examples |
75 | 60 |
|
76 | 61 | > Runnable examples can be found in the [examples folder](examples/). |
77 | 62 |
|
78 | | -##### Inject `firebase` and `todos` |
| 63 | +##### Pass `todos` as a prop |
79 | 64 |
|
80 | | - > Note: The value of `todos` is analogous to https://my-firebase.firebaseio.com/todos. |
| 65 | + > Note: The value of `todos` is the path to your data in Firebase. This is equivalent to `firebase.database().ref('todo')`. |
81 | 66 |
|
82 | 67 | ```js |
83 | | -function mapPropsToSubscriptions() { |
84 | | - return { todos: 'todos' } |
| 68 | +const mapFirebaseToProps = { |
| 69 | + todos: 'todos' |
85 | 70 | } |
86 | 71 |
|
87 | | -export default connect(mapPropsToSubscriptions)(TodoApp) |
| 72 | +export default connect(mapFirebaseToProps)(TodoApp) |
88 | 73 | ``` |
89 | 74 |
|
90 | | -##### Inject `todos` and a function that adds a new todo (`addTodo`) |
| 75 | +##### Pass `todos` and a function that adds a new todo (`addTodo`) as props |
91 | 76 |
|
92 | 77 | ```js |
93 | | -function mapPropsToSubscriptions() { |
94 | | - return { todos: 'todos' } |
95 | | -} |
| 78 | +const mapFirebaseToProps = (props, ref) => ({ |
| 79 | + todos: 'todos', |
| 80 | + addTodo: todo => ref('todos').push(todo) |
| 81 | +}) |
96 | 82 |
|
97 | | -function mapFirebaseToProps(firebase) { |
98 | | - return { |
99 | | - addTodo: function(todo) { |
100 | | - firebase.child('todos').push(todo) |
101 | | - } |
102 | | - } |
103 | | -} |
| 83 | +export default connect(mapFirebaseToProps)(TodoApp) |
| 84 | +``` |
| 85 | + |
| 86 | +##### Pass `todos`, `completedTodos`, a function that completes a todo (`completeTodo`) and one that logs in as props |
104 | 87 |
|
105 | | -export default connect(mapPropsToSubscriptions, mapFirebaseToProps)(TodoApp) |
| 88 | +```js |
| 89 | +const mapFirebaseToProps = (props, ref, { auth }) => ({ |
| 90 | + todos: 'todos', |
| 91 | + completedTodos: { |
| 92 | + path: 'todos', |
| 93 | + orderByChild: 'completed', |
| 94 | + equalTo: true |
| 95 | + }, |
| 96 | + completeTodo = id => ref(`todos/${id}/completed`).set(true), |
| 97 | + login: (email, password) => auth().signInWithEmailAndPassword(email, password) |
| 98 | +}) |
| 99 | + |
| 100 | +export default connect(mapFirebaseToProps)(TodoApp) |
106 | 101 | ``` |
107 | 102 |
|
108 | | -##### Inject `todos`, `completedTodos` and a function that completes a todo (`completeTodo`) |
| 103 | +### `<Provider firebaseApp>` |
| 104 | + |
| 105 | +By default `connect()` will use the [default Firebase App](https://firebase.google.com/docs/reference/js/firebase.app). If you have multiple Firebase App references in your application you may use this to specify the Firebase App reference available to `connect()` calls in the component hierarchy below. |
| 106 | + |
| 107 | +If you *really* need to, you can manually pass `firebaseApp` as a prop to every `connect()`ed component, but we only recommend to do this for stubbing `firebaseApp` in unit tests, or in non-fully-React codebases. Normally, you should just use `<Provider>`. |
| 108 | + |
| 109 | +#### Props |
| 110 | + |
| 111 | +* `firebaseApp` (*[App](https://firebase.google.com/docs/reference/js/firebase.app.App)*): A Firebase App reference. |
| 112 | +* `children` (*ReactElement*): The root of your component hierarchy. |
| 113 | + |
| 114 | +#### Example |
109 | 115 |
|
110 | 116 | ```js |
111 | | -function mapPropsToSubscriptions() { |
112 | | - return { |
113 | | - todos: 'todos', |
114 | | - completedTodos: function(firebase) { |
115 | | - return firebase.child('todos').orderByChild('completed').equalTo(true) |
116 | | - } |
117 | | - } |
118 | | -} |
| 117 | +import { initializeApp } from 'firebase' |
119 | 118 |
|
120 | | -function mapFirebaseToProps(firebase) { |
121 | | - return { |
122 | | - completeTodo: function(id) { |
123 | | - firebase.child('todos').child(id).child('completed').set(true) |
124 | | - } |
125 | | - } |
126 | | -} |
| 119 | +const firebaseApp = initializeApp({ |
| 120 | + databaseURL: 'https://my-firebase.firebaseio.com' |
| 121 | +}) |
127 | 122 |
|
128 | | -export default connect(mapPropsToSubscriptions, mapFirebaseToProps)(TodoApp) |
| 123 | +ReactDOM.render( |
| 124 | + <Provider firebaseApp={firebaseApp}> |
| 125 | + <MyRootComponent /> |
| 126 | + </Provider>, |
| 127 | + rootEl |
| 128 | +) |
129 | 129 | ``` |
130 | 130 |
|
131 | 131 | ## License |
|
0 commit comments