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-send-action

v0.2.1

Published

react-send-action is a small library that hook up a `send-action` store into your React app, works not unlike react-redux

Downloads

8

Readme

react-send-action

NPM version build status Downloads js-standard-style

react-send-action is a small library that hook up a send-action store into your React app, works not unlike react-redux.

Installation

$ npm i react-send-action --save

What is send-action

send-action is meant to be the smallest, simplest redux-like state management library. The focus is on providing a concise method for triggering actions, and on avoiding complex middleware & development dependencies.

The API is significantly different from redux, but the pattern is similar.

Using send-action you trigger actions, modify state based on those actions, and listen to the changes to render your application.

API

<Provider createStore={createStore}>

Makes the send-action store available to the connect() calls in the component hierarchy below. Normally, you can’t use connect() without wrapping the root component in <Provider>.

Connect(mapProps, mapActionHandlers, mapStatics)(Component)

Connects a React component to a send-action store.

It does not modify the component class passed to it. Instead, it returns a new, connected component class, for you to use.

Usage

TLDR:

Container component: select props and actionHandler to Container.

import React, { PropTypes } from 'react'

import { Connect } from 'react-send-action'
import App from './app'

// select user from store
export default Connect(
  (store, props) => {
    let { user } = store.state()
    return {
      user
    }
  },
  (store, props) => {
    let { user } = store.state()
    return {
      user
    }
  }
)(App)

Root of the app: hook store in to the app.

import React from 'react'
import { render } from 'react-dom'
import Provider from '../'

import AppContainer from './appContainer'
import initialState from './initialState'
import actionHandler from './actionHandler'

const createStore = {
  actionHandler,
  initialState
}

render((
  <Provider createStore={createStore}>
    <AppContainer />
  </Provider>
), document.body)

Longer version

Prepare actionHandler and initialState that will be used to createStore

  • Create initialState for your whole application
const initialState = {
  user: {
    name: 'fraserxu'
  }
}

export default initialState
  • Create a actionHandler.js to trigger changes action and reduce new State
/**
 * Store action handler
 * @param  {Object} action Object
 * @param  {Object} state  Object
 * @return {Object} new State
 */
export default function onaction (action, state) {
  switch (action.type) {
    case 'updateUser':
      const { user } = action.payload
      return {
        ...state,
        user
      }
  }
}

Hook your createStore object to the Provider, this step does two things:

  1. Create a store object on the App context, so your child or grand-child component could have access to the store via this.context.store
  2. Hook the onchange event to the Provider component itself so it could update the internal state and cause the app to do a re-render

Provider works on both client side and server side. To hook the store to your app, you can do:

Provider(client side)

import { Provider } from 'react-send-action'
import React from 'react'
import { render } from 'react-dom'

import AppContainer from './appContainer'
import initialState from './initialState'
import actionHandler from './actionHandler'

const createStore = {
  actionHandler,
  initialState
}

render((
  <Provider createStore={createStore}>
    <AppContainer />
  </Provider>
), document.body)

Provider(server side)

renderToString(
  <Provider createStore={createStore}>
    <AppContainer />
  </Provider>
)

There are three way to consume state and dispatch action in your child componet.

First way is to access to store object directly from this.context.store, which is not recommended as

Using context makes your components more coupled and less reusable, because they behave differently depending on where they're rendered.

import React from 'react'

class App extends React.Component {
  onClickHandler () {
    // dispatch an toggle event
    this.context.store(
      'type': 'updateUser',
      'payload': {
        name: 'someone else'
      }
    )
  }
  render () {
    const { user } = this.context.store.state()
    return (
      <div>
        <span>{user.name}</span>
        <button onClick={this.onClickHandler}>Toggle</button>
      </div>
    )
  }
}

App.contextTypes = {
  store: React.PropTypes.func.isRequired
}

export default App

The other way to use it is through container component. There are lots of reasons to use container component, the most obvious one is to seperate the data logic from your view component, most of your view should be dumb and only takes in props and render the view, so it's very easy to test and reuse.

You should always only handle your data logic inside the high order component, and pass down the state and dispatchers down through props.

First presume we have a dump home page component

import React, { PropTypes } from 'react'

class App extends React.Component {
  static propTypes = {
    user: PropTypes.object
  }
  render () {
    const { user } = this.props
    return (
      <span>{user.name}</span>
    )
  }
}

export default App

And then we use the a helper function to grab the user props from our store

import React, { PropTypes } from 'react'

import App from './app'

class AppContainer extends React.Component {
  render () {
    let { user } = this.context.store.state()
    return (
      <HomePage user={user} />
    )
  }
}

AppContainer.contextTypes = {
  store: PropTypes.func.isRequired
}

export default AppContainer

For more details, please check the example directory.

The last way and easiest way is to use the builtin Connect component which hook up the props, actionsHandlers and static method to the wrappedComponent.

import React from 'react'
import { Connect } from 'react-send-action'

import App from './app'
import { fetchStats } from './common/utils/api'

const AppContainer = Connect(
  (store, props) => {
    const { user, stats } = store.state()
    return {
      user,
      stats
    }
  },
  (store, props) => {
    return {
      setUser: (user) => {
        store({
          type: 'userSignedIn',
          payload: {
            user
          }
        })
      }
    }
  },
  {
    actions: {
      stats: fetchStats
    }
  }
)(App)

export default AppContainer

License

MIT