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

reduceless

v0.2.4

Published

Redux helpers

Downloads

72

Readme

Reduceless

Simple abstraction over Redux to make state management as easy as React's vanilla setState() but with advantages of Redux.

The idea is easy: you connect component to a slice of your Redux state to give this component full control over this part of the state. It can read from this state and write to it in React style with setState and replaceState. You don't need any custom reducers, actions or constants to do it. Just read state and write to it.

Don't worry you are still able to use Redux in the normal way. It's just set of helper to avoid boilerplate for simple actions.

Installation

npm install reduceless --save

How to use:

1.wrap your root reducer with wrapReducerWithSetGlobalState

import {wrapReducerWithSetGlobalState} from 'reduceless';

const reducer = wrapReducerWithSetGlobalState(
  // Your normal reducers are going here
  // combineReducers({
  //   reducer1,
  //   reducer2,
  // })
);

2.connect your component to a slice of your state

import {connectSlicedState} from 'reduceless';

@connectSlicedState('pages.blogs.data.activePost')
const PostForm = ({state, setState, replaceState}) => {
  return (
    <div>
      <input
        type="checkbox"
        checked={state.checked}
        onChange={e => setState({'checked': !state.checked})}/>
      <br/>
      value: {state.checked.toString()}
    </div>
  )
}

PostForm component will recieve part of your Redux state located at pages.blogs.data.activePost in state prop. Component can change it using setState(newState) and replaceState(newState) props. This path could even not exist. It will be created automatically when component will write to it.

3.[Optional] Use can use replaceStateByPath and setStateByPath action creators for advanced scenarios.

import {connectSlicedState} from 'reduceless';
import _ from 'lodash';

const Form = ({checked, setChecked}) => {
  return (
    <div>
      <input
        type="checkbox"
        checked={checked}
        onChange={e => setChecked({'checked': !state.checked})}/>
      <br/>
      value: {checked.toString()}
    </div>
  )
}

export default connect(
  (state, props) => ({
    checked: _.get(state, 'pages.blogs.data.activePost'),
  }),
  dispatch => ({
    setChecked: checked => dispatch(replaceStateByPath('pages.blogs.data.activePost', checked)),
  })
)(Form);

Still no actions, reducers or constants.

4.[Optional] use initialReducer // TODO

Basic API

###wrapReducerWithSetGlobalState(reducer) Wraps your reducer(probably at root level but you can use it in any level of your reducers tree) with another reducer that catches events sent by reduceless(SET_STATE_BY_PATH, REPLACE_STATE_BY_PATH).

###connectSlicedState(path)(component) Connects your component to a slice of your redux state located at path. Sends following props to the component:

  1. state - slice of the state located at path. It doesn't matter what exaclty is stored there. It could be object, array, simple value. Actually there could be no such path in your state at all. In that case you will get state === undefined so you can use defaultProps to populate this prop.

  2. setState(newState) – action (already wrapped in dispatch) that will merge slice of the state located at path with newState. If this path does not exist in your redux state it will be created. Calls setStateByPath under the hood.

  3. replaceState(newState) – action (already wrapped in dispatch) that will replace slice of the state located at path with newState. If this path is does not exist in your redux state it will be created. Calls replaceStateByPath under the hood.

Advanced API

###setStateByPath(path, newState) Action creator that merges state located by path with newState.

dispatch(setStateByPath('posts.3.data', {title: 'new title'}))

replaceStateByPath(path, newState)

Action creator that merges state located by path with newState.

dispatch(replaceStateByPath('posts.3.data.title', 'new title'))