npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-insula

v2.1.6

Published

`react-insula` allows React components to be directly connected to [Insula](https://github.com/chandlerprall/insula) stores, allowing easy state transformations and subscriptions.

Downloads

15

Readme

react-insula allows React components to be directly connected to Insula stores, allowing easy state transformations and subscriptions.

Examples

Todo [demo] [code]

Counter [demo] [code]

Installation

npm

npm install --save --react-insula

yarn

yarn add react-insula

Creating and attaching state

Before connecting a stateful component, the state has to be exposed to the React DOM tree. This is done by wrapping your application with the Provider component.

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-insula';

const initialState = {
    deeply: {
        nested: {
            object: 'value'
        }
    },
    foo: 'bar'
};
const store = new Store(initialState);

ReactDOM.render(
    <Provider store={store}>
        <div>... rest of application goes here ...</div>
    </Provider>,
    document.getElementById('application')
);

Subscribing components

To pull values from state into a component and have the component update when those values change, wrap the component with the connect function. This works for both Function components and Component classes. Insula uses selectors to specify which parts of state you want to access.

import React from 'react';
import {connect} from 'react-insula';

function MyComponent({theValue, foo}) {
    return (
        <div>
            theValue: {theValue}
            <br/>
            foo: {foo}
        </div>
    );
}

// we want to access two values from the state: `deeply.nested.object` and `foo`
const selectors = [
    ['deeply', 'nested', 'object'],
    ['foo']
];

const transformer = ([deeplyNestedObject, foo]) => {
    return {
        theValue: deeplyNestedObject,
        foo
    };
};

export default connect(selectors, transformer)(MyComponent);

Transformers

As the above example demonstrates, the first argument to a transformer function is an array with the selected state values. The object returned by a transformer will be merged with any props set by the parent and passed down to the child component.

Accessing props

Sometimes it is useful to access the component's props in the transformer. These props are always passed to the transformer function as an additional value in the array.

Parent.js

function Parent() {
    return (
        <Child foo="bar" baz={[1,2,3]}/>
    );
}

Child.js

export default connect(
    [['stateValue']], // one selector
    ([stateValue, props]) => {
        return {
            stateValue: props.includeStateValue ? stateValue : null
        };
    }
)(ChildComponent);

Dispatching events

Insula's state management is event driven so all connected views are also given a dispatch function that takes an event type and optional payload.

function MyComponent({dispatch, subject, body}) {
    const onClick = () => dispatch('SEND_MESSAGE', {subject, body});
    return (<button onClick={onClick}>Send</button>);
}

export default connect(
    [ ['message', 'subject'], ['message', 'body'] ],
    ([subject, body]) => ({subject, body})
)(MyComponent);

Bound dispatches

A key philosophy behind react-insula is that views should not know what is supposed to happen. Instead, they should be given a function that does something at a given interaction, but they don't care what. Transformers are passed an object as the second argument with a bindDispatch method which allows them to create dispatcher functions. The event payload can optionally be curried onto the dispatch as well.

function MyComponent({resetForm, sendMessage}) {
    const onClick = () => dispatch('SEND_MESSAGE', {title: 'Hello', message: 'World'});
    return (
        <div>
            <button onClick={sendMessage}>Send</button>
            <button onClick={resetForm}>Reset</button>
        </div>
    );
}

export default connect(
    [ ['message', 'subject'], ['message', 'body'] ],
    ([subject, body], {bindDispatch}) => {
        return {
            resetForm: bindDispatch('RESET_FORM'), // no payload defined, the view could optionally add one
            sendMessage: bindDispatch('SEND_MESSAGE', {subject, body}) // payload is defined, the view can't do anything but call the function
        };
    }
)(MyComponent);

Runtime event listeners

While event listeners can be added to the store directly, sometimes an event only makes sense in the context of a component, or maybe a mounted component needs to Do Something Else in response to an event. These runtime event listeners can be specified by passing a configuration object to connect.

export default connect(
    [[]],
    ([state]) => ({}),
    {
        listeners: {
            SEND_MESSAGE: (payload, {dispatch}) => {
                const {subject} = payload;
                dispatch('RECORD_ANALYTICS', {eventType: 'sentMessage', subject});
            }
        }
    }
)(MyComponent);

The second parameter passed to the listener function provides the dispatch, getState, getPartialState, setState, and setPartialState methods from the Insula store.

Runtime event listeners are added during the componentDidMount lifecycle and removed at componentWillUnmount. Additionally, the listener's this context is your component, allowing you to access the instance methods.

class MyComponent extends Component {
    reactToEvent() {
        // ... do something
    }

    render() {return <div/>;}
}

export default connect(
    [[]],
    ([state]) => ({}),
    {
        listeners: {
            'EVENT_TYPE': () => {
                 this.reactToEvent();
             }
         }
    }
)(MyComponent);