react-copycat v0.2.1
react-copycat
Vitals
Other Stats
What is it?
react-copycat is a declarative state-sharing add-on library for usage with React with minimal boilerplate. It allows you to declare what a component 'publishes', and what 'subscriptions' a component holds, if any.
Who is this for?
In short, this is for anyone who needs to manage/share state between components and wants to do so with no boilerplate and in a declarative manner. In particular, projects not already using another state-management/sharing library, or projects which feel their state-management library is too tedious and/or complex may find react-copycat attractive.
This is not meant to replace something like Redux, in apps where its features are deemed necessary. react-copycat can be seen as filling a gap somewhere between apps not currently managing global state and apps using something like Redux or Flux.
What do you get?
Selective State Visibility
Only the state attributes a publisher exposes will be accessible to subscribers
and subscribers only get read-access to a copy from the Observer
. This can
decrease the likelihood of an unpleasant suprise.
Declarative state-sharing and propagation
A subscriber has any state components it subscribes to (provided the publisher exposes it), injected into its properties. Any time a publisher changes its state, any published values are updated in the Observer
state and re-injected to subscriber properties.
Scoped Observers
The Observer
component is not implemented as a singleton. The Observer
component can be nested in other observers and/or does not need to wrap the
whole app, although this is a common use-case. In practice, this means you can
separate groups of composed components into different Observers
, allowing
scoped state-sharing without worrying about polluting the global state
namespace. In other words, the state is only as global as you choose to make it.
What don't you get?
Boilerplate
Actions
Reducers
A Time-Travelling Debugger
Note: If these features are necessary, they can still be used with react-copycat, as it makes no assumptions about what is causing a publisher to update its state. That being said, these features are not included nor required for general use.
Getting Started
Installation
With yarn
yarn add react-copycat
With npm
npm install --save react-copycat
Usage
// App.js
import React, { Component } from 'react';
import PublishingComponent from './PublishingComponent';
import SubscribingComponent from './SubscribingComponent';
import { Observer } from 'react-copycat';
class App extends Component {
constructor(props) {
super(props) {
// Anything else.
}
}
render() {
return (
<Observer>
<PublishingComponent
publish={{
id: 'myUniquePublishingComponent',
state: [
'publicState'
]
}}
/>
<SubscribingComponent
subscribe={[{
// Array of subscriptions.
id: 'myUniquePublishingComponent',
props: {
// Injected prop name | Exposed name
sharedPublic: 'publicState'
sharedPrivate: 'privateState' // Undefined
}
}]}
/>
// Another component of the same type that doesn't subscribe.
<SubscribingComponent
sharedPublic="Didn't subscribe"
sharedPrivate="Didn't subscribe"
/>
</Observer>
);
}
};
export default App;
// PublishingComponent.js
import React from 'react';
import { Observable } from 'react-copycat';
export default class extends Observable {
constructor(props) {
super(props);
this.state = {
publicState: 'Open to subscriptions!',
privateState: 'Secret!'
}
}
render() {
return (
<div>
<div>Public State: {this.state.publicState}</div>
<div>Private State: {this.state.privateState}</div>
</div>
);
}
};
// SubscribingComponent.js
import React, { Component } from 'react';
export default class extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div>Public Published state from Publisher: {this.props.sharedPublic}</div>
<div>Private State from Publisher: {this.props.sharedPrivate || 'Cannot retrieve'}</div>
</div>
);
}
};
How does it Work?
The package exports two classes, Observer
and Observable
. Observer
is a
wrapper component that can be accessed by any of its children. Children
publish by registering the state they wish to expose to the Observer
.
Components which do this are known as Publishing
Components, and they extend
the Observable
class (which extends React.Component
). Any component can
subscribe to a Publishing
component, and components which do so are
known as Subscribing
components. Subscribing
components do not need to
extend Observable
(and can extend React.Component
instead) unless they are
also a Publishing
component. The decision of what to publish or subscribe to
is done declaratively through properties
Note: Programmatic control will likely be added in a future version, allowing things like e.g. pausing and resuming subscriptions.
Under the hood, the Observer
stores a copy of published state in its own
state, and classes extending Observable
update the values as a callback to
their setState(updater, callback)
method, which is also a passthrough to
React's setState(updater, callback)
. Any Subscribing
components will have
access to the requested state (if the publisher exposes it) through property
injection.
That's about it so far.