Skip to content

ShareDB and React Redux #380

@eMarek

Description

@eMarek

I am wondering how people use ShareDB in combination with React Redux?

I made a proof of concept which works, but it has few disadvantages. To be honest, it is kind of nasty. :D For start let me tell you that big portion of my frontend was already done before starting to think about using ShareDB. This means that all my actions, reducers and state were designed and completed already in the past. I didn't want to change this, because it would mean rewriting almost entire app. So I came across solution described below.

Part 1: Opening connection and creating local Doc.
There is nothing really special about this.

import ReconnectingWebSocket from 'reconnecting-websocket'
import sharedb from 'sharedb/lib/client'

var socket = new ReconnectingWebSocket('ws://localhost:8080');
var connection = new sharedb.Connection(socket);
var doc = connection.get('myCollection', 'myDocument');
doc.subscribe(() => console.log("SUBSCRIBED!"))

Part 2: Looking for a diff and submitting OP.
I want to realtime sync only one part of Redux state (state.myReducer.myData). I will probably use watcher in the future, but for proof of concept I made a simple React component.

import jsondiff from 'json0-ot-diff'
import { useSelector } from 'react-redux'

export const Watcher = () => {
  const myData = useSelector(state => state.myReducer.myData)
  const diff = jsondiff(doc.data, myData)
  if (diff.length > 0) {
    doc.submitOp(diff)
  }
  return null
}

Part 3: Dispatching doc.data on op event.
Since my local changes are already in the store I need to update Redux's state only on changes from server.

import Store from './redux/Store'
import { updateMyData } from './redux/actions/MyDataActions'

doc.on('op', (op, localChange) => {
  if (!localChange) {
    Store.dispatch(updateMyData(doc.data))
  }
})

Under the hood updateMyData action sends doc.data into the reducer which replaces entire JSON with the one from doc.data. This is the part which I hate the most. Also this happens on every op event. This means that anytime some other client makes a change my redux state updates. It is not even near perfect.

What do you think about this solution? Which approach do you use?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions