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

redux-fragments

v0.1.10

Published

A methodalogy for setting up for react/redux code for optimum usability.

Downloads

45

Readme

redux-fragments

WORK IN PROGRESS

This is a small helper library to assist developers in writing their UI with a fragment architecture.

Please checkout my blog for a better explanation of redux-fragments! Checkout the redux-fragments-boilerplate to see a sample in action!

What are redux-fragments?

Sharing React components is easy, but what about all the effort gone into redux actions and reducer handlers? Ideally we can share not only the React component, but also the redux state, the handlers and the actions. Arranging your UI architecture with redux-fragments will help you achieve this in a testable, extendible and overwritable manner.

The structure

A redux-fragment consists of 4 majors pieces.

Action Type Creator

Action types are pretty self explanatory,. The prefix very is important. Its key to reusing a fragment without one instance affecting another.

export function createActionTypes(prefix = '') {
	return {
    CLICK_BUTTON: `${prefix}CLICK_BUTTON`,
    SELECT_TAB: `${prefix}SELECT_TAB`,
    CHANGE_PAGE: `${prefix}CHANGE_PAGE`
	};
}

Action Creator

Action Creator takes in actionTypes map, created from createActionTypes above. Since the action types were instantiated with a prefix, when these actions are fired, they will also use this prefix, which allows one fragment to be independant from another, evne though they share the same code.

export function createActions(actionTypes) {
	function clickButton() {
    return {
      type: actionTypes.CLICK_BUTTON,
      payload: {}
    };
  }

	return {
    clickButton
	};
}

Reducer Handlers

The key difference between a regular redux reducer and fragment handlers is that the fragment handlers do not actually plug themselves into the redux state. In order to use the fragment, you must plug these reducer handlers into your redux state somewhere. This allows you to instantiate many separate instances of the state, which would allow you to show multiple fragments on screen at one time if needed.

import { createActionTypes } from './actionTypes.js';

export const initialState = {
  showText: '',
};

export const createHandlers = (prefix) => {
	const actionTypes = TimelineActionTypes.createActionTypes(prefix);
	const handlers = {};

	handlers[actionTypes.CLICK_BUTTON] = (state, payload) => {
		const newState = {...state);
    newState.showPopup = 'text';
		return newState;
	};

	return handlers;
};

React Component

Finally, the last piece of the fragment is the React Component. Its just a regular React component that will take in the redux state of the fragment and actions as props. It can also take in other props as attributes.

  class ButtonSample extends React.Component {

    static propTypes = {
      buttonSample: PropTypes.object, // state
      title: PropTypes.string, // component attribute
      clickButton: PropTypes.func, // action\
    };

    renderButton() {
      return <button onClick={() => this.props.clickButton()}>ClickMe</button>;
    }

    render() {
      return (
        <div>
          <span>{this.props.title}</span>
          <span>{this.props.sample.text}</span>
        </div>
      );
    }
  }

Putting it all together

Now that we have all the pieces to the fragment we can plug it in. First we have to create a spot in the redux state for it and hook up the handlers. Generally we do this in a typical redux reducer.

import { attachState, executeHandlers } from 'redux-fragment';
import { createActionTypes } from '../fragments/buttonSample/actionTypes.js';
import { createActions } from '../fragments/buttonSample/actionCreator.js';
import { initialState, createHandlers } from '../fragments/buttonSample/reducerHandlers.js';

export const prefix = 'SAMPLE__';

const fragments = {
	buttonSample: {
		initialState: {
			...initialState
		},
		handlers: {
			...createHandlers(prefix)
		}
	}
};

const initialState = {
  root: {}
};

const handlers = {};

const getInitialState = () => {
	return attachState(initialState, fragments);
};

// This function is hooked up to redux store
export function sample(state = getInitialState(), action) {
	return executeHandlers(state, action, handlers, fragments);
}

Then we have to connect our React component to our actions and state we created.

import React, {PropTypes} from 'react';
import { connect } from 'react-redux';
import { prefix } from '../reducers/sampleReducer.js';
import { createActionTypes } from '../fragments/buttonSample/actionTypes.js';
import { createActions } from '../fragments/buttonSample/actionCreator.js';
import { ButtonSample } from '../fragments/buttonSample/component.js';
import { initialState, createHandlers } from '../fragments/buttonSample/reducerHandlers.js';

export class SampleContainer extends React.Component {
	static propTypes = {
	};

	componentWillMount() {
	  const enhance = connect({
	    buttonSample: (store) => store.sample.fragments.buttonSample
	  }, createActions(createActionTypes(prefix)));
	  this.ButtonFragment = enhance(ButtonSample);
	}

	render() {
		const ButtonFragment = this.ButtonFragment;
		return (
      <ButtonFragment title="Button Fragment"/>
		);
	}
}

That's it!

The explanation

So it works, great, why go through all the extra effort?

Sharing state can get messy

Trying to share the same state for different parts of the applications causes problems. For example, if you ever need to show both those parts of the application at once, you won't be able to because they share state. Also when you share the same state, you often have to make changes that affect all usages of the shared code. With a fragment you can extend of overwrite to avoid having to affect other areas of the code

Large modules of code are rarely exactly the same

Fragments are completely extendible and overwritable in every way. If you ever need to reuse code, you'll have no problem extending it to make those specific tweaks.

Helps separate duties

Building your code as fragments encourages developers to think ahead about separating duties to produce decoupled code.

Great for testing

With fragments, you can test each one independently from the rest of the code.

TODO List

  • Missing pretty check marks
  • proofread
  • override function
  • plug this into synposis
  • more test cases
  • loader isn't setup for sampleFragments
  • remove lodash
  • immutablejs
  • recursive attachState