Package Exports
- @jsonjoy.com/collaborative-react
- @jsonjoy.com/collaborative-react/lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@jsonjoy.com/collaborative-react) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
JSON CRDT integrations with React.js
React hooks, context helpers, and lightweight render-prop components for binding
React UI to json-joy CRDT models and nodes.
Installation
npm install json-joy @jsonjoy.com/collaborative-react reactWhat this package provides
- Context providers for
ModelandNodeApi - Reactive hooks for model ticks, model views, node views, and path access
- Typed path hooks for object/array/string nodes
- Render-prop components (
UseModel,UseNode) for declarative subscriptions
Quick start
import * as React from 'react';
import {ModelCtx, useModelView, useStr} from '@jsonjoy.com/collaborative-react';
import {Model} from 'json-joy/lib/json-crdt';
const model = Model.create({title: 'Hello'});
function TitleEditor() {
const root = useModelView();
const title = useStr('/title');
return (
<div>
<p>{root.title}</p>
<button onClick={() => title?.ins(title.view().length, '!')}>Append !</button>
</div>
);
}
export const App = () => (
<ModelCtx model={model}>
<TitleEditor />
</ModelCtx>
);Context API
Providers
ModelCtx: provides aModelvia contextNodeCtx: provides aNodeApivia context
When using ModelCtx, both the model and model.api are available to hooks.
Context hooks
useCtxModel()/useCtxNode(): optional context access (can returnundefined)useCtxModelStrict()/useCtxNodeStrict(): strict access (throws if missing)
Custom isolated context
Use createNodeCtx() when you need a separate, isolated node/model context in the
same component tree.
Hooks
Model hooks
useModelTick(model?): subscribe to every model tickuseModelView(model?): subscribe to model view snapshotuseModel(selector, model?): derive reactive values from modeluseModelTry(selector, model?): safe variant returningundefinedon selector error
Node hooks
useNodeEvents(event, listener, node?): subscribe to node events (self,child,subtree)useNodeEffect(event, listener, node?): effect wrapper with auto-unsubscribeuseNodeChange(event, node?): re-render on node change, returns lastChangeEventuseNode(node?, event?): subscribe and return nodeuseNodeView(node?, event?): subscribe and return node view
Path hooks
usePath(path, node?, event?): read nested node by pathusePathView(path, node?, event?): read nested node view by pathuseObj(path?, node?, event?): typed object node hookuseArr(path?, node?, event?): typed array node hookuseStr(path?, node?, event?): typed string node hook
Components
UseModel
Render-prop component that re-renders when model changes.
import {UseModel} from '@jsonjoy.com/collaborative-react';
<UseModel
model={model}
render={(m) => <pre>{JSON.stringify(m.api.view(), null, 2)}</pre>}
/>UseNode
Render-prop component that re-renders on node events.
import {UseNode} from '@jsonjoy.com/collaborative-react';
<UseNode
node={model.s.$}
event="subtree"
render={(node) => <pre>{JSON.stringify(node.view(), null, 2)}</pre>}
/>Notes
- Most hooks can infer the target model/node from context when used under
ModelCtxorNodeCtx. - Use strict hooks only when you know a provider is present.
useModelViewonly re-renders when the view identity changes, whileuseModelTickre-renders on every model change.