From bfe80536c119b642bf168014f86181e9a98d34a4 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Thu, 6 Jul 2017 11:08:25 +0100 Subject: [PATCH] Create redux.md --- docs/redux.md | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 docs/redux.md diff --git a/docs/redux.md b/docs/redux.md new file mode 100644 index 00000000..818b4127 --- /dev/null +++ b/docs/redux.md @@ -0,0 +1,125 @@ +# Usage with Redux + +Although RNFirebase usage requires a React Native environment, it isn't tightly coupled which allows for full flexibility +when it comes to integrating with other modules such a [`react-redux`](https://github.com/reactjs/react-redux). If you wish to use +a Redux library designed for Firebase, we suggest taking a look at [`react-redux-firebase`](http://docs.react-redux-firebase.com/history/v2.0.0/docs/recipes/react-native.html) +for implementation with this module. + +## Standalone integration + +Although the following example works for a basic redux setup, it may differ when integrating with other redux middleware. +Imagine a simple TODO app, with redux we're able to abstract the Firebase logic out of components which allows for greater +testability and maintainability. + +?> We use [`redux-thunk`](https://github.com/gaearon/redux-thunk) to provide async actions. + +### Action Creators + +```js +// Actions +export const subscribe = () => { + return (dispatch) => { + firebase.database().ref('todos').on('value', (snapshot) => { + const todos = []; + + snapshot.forEach((childSnapshot) => { + todos.push({ + id: childSnapshot.key, + ...(childSnapshot.val()), + }) + }) + + dispatch({ + type: 'TODO_UPDATE', + todos, + }) + }) + } +} + +// Methods +export const addTodo = text => { + firebase.database().ref('todos').push({ + text, + visible: true, + }) +} + +export const completeTodo = id => { + firebase.database().ref(`todos/${id}`).update({ + visible: false, + }) +} + +``` + +Instead of creating multiple actions which the reducers handle, we instead subscribe to the database ref and on any changes, +send a single action for the reducers to handle with the data which is constantly updating. + +### Reducers + +Our reducer now becomes really simple, as we're able to simply update the reducers state with whatever data has been returned +from our Firebase subscription. + +```js +const todos = (state = {}, action) => { + switch (action.type) { + case 'TODO_UPDATE': + return { ...action.todos }; + } + + return state; +} + +export default todos; +``` + +### Component + +We can now easily subscribe to the todos in redux state and get live updates when Firebase updates. + +```js +import React from 'react'; +import { FlatList } from 'react-native'; +import { connect } from 'react-redux'; +import { subscribe, addTodo, completeTodo } from '../actions/TodoActions.js'; +... + +class Todos extends React.Component { + + componentDidMount() { + this.props.dispatch( + subscribe() + ); + } + + onComplete = (id) => { + this.props.dispatch( + completeTodo(id) + ); + }; + + onAdd = (text) => { + this.props.dispatch( + addTodo(text) + ); + }; + + render() { + return ( + + ); + } +} + +function mapStateToProps(state) { + return { + todos: state.todos, + }; +} + +export default connect(mapStateToProps)(Todos); +```