<commit_before># Redux Segmentize
By: <NAME>

Automatically manage component-based state with redux.

The recommended Container/Component setup is nice, but sometimes you need to re-use components throughout your app that need to manage their own state.  Setting up separate reducers for each instance of these components is a pain.  Now you can manage them automatically.  Set your reducer up once, then re-use it for each component instance.

### Installation
`npm install --save redux-segmentize`

### Step 1: Segmentize your Reducers
Build your reducers the way you would for managing just one instance, then wrap them like so with `segmentReducer()`:

```javascript
import { segmentReducer } from 'redux-segmentize';

function clicksReducer(state = 0, action) {
    switch(action.type) {
        case 'CLICK_COOL_BUTTON':
            return state + 1
    }

    return state;
}

const rootReducer = combineReducers({
    clicks: segmentReducer(clicksReducer),
    ...
});
```

### Step 2: Binding components to segmentized reducers
Build your components as you normally would.  Use `segmentConnect` instead of `react-redux`'s `connect`.  Segment connect detects which props are segments, then it sets up a new property within that segment where it can store values for the state of your component.  For example:

```javascript
import React from 'react';
import { segmentConnect } from 'redux-segmentize';

const CoolButton = props => {
    return (
        <div className="cool-button-component">
            <button>Push me</button>
            <div>Clicked { clicks } times.</div>
        </div>
    )
}

const select = state => {
    return {
        clicks: state.clicks
    }
}

export default segmentConnect(select)(BaseCounter);
```
Literally the only thing you need to change at this point is to use `segmentConnect` instead of `react-redux`'s `connect`.

### Step 3: Update segmentized state
Using normal actions can be a problem, since at this point, nothing will differentiate actions dispatched by each instance of `CoolButton`.  Once again, set up your actions as you normally would.  Then, instead of referencing them directly, you can inject them into your component's props via `segmentConnect`.  Then you can reference them from props.  

```javascript
import React from 'react';
import { segmentConnect } from 'redux-segmentize';

const actions = {
    click: () => ({ type: 'CLICK_COOL_BUTTON' })
}

const CoolButton = props => {
    return (
        <div className="cool-button-component">
            <button onClick={props.click()}>Push me</button>
            <div>Clicked { props.clicks } times.</div>
        </div>
    )
}

const select = state => {
    return {
        clicks: state.clicks
    }
}

export default segmentConnect(select)(BaseCounter, actions);
```

Notice, we've updated the onClick listener for the button.  Also, dispatch is automatically called for you.  In this case, executing the `click` function will dispatch your click event, appending a `subscriberID` attribute to the resulting object with the id of your component (it uses the `id` prop if available, otherwise it generates a unique identifier).  Your segmented reducer then applies that action to your reducer, storing the resulting value under your component's identifier, within your segment.  Your component also looks up that value with the same identifier.

Now you can simply use your component anywhere in your app, and it will automatically manage it's own state in Redux.  For example:

```javascript
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
etc.
```

Each instance of `CoolButton` has it's own place in your store, and fires it's own actions, all using the same code for your actions and reducer.

### Extracting values from segments, using normal components and react-redux
If you want another component to extract values from your segments (say, to make an AJAX request with), you can use the `extractProp` function.

First, you'll need to add a `subscriberID` prop (Alternatively `id` works as well) to your instance of `CoolButton` you want to report on.
```javascript
<CoolButton subscriberID="cool-button-1"/>
```

Next, let's set up the reporting component.

```javascript
import React from 'react';
import { extractProp } from 'redux-segmentize';
import { connect } from 'react-redux';

const actions = {
    myCustomReportingAction: clicks => ({ type: 'REPORT_CLICKS', amount: clicks })
}

const ReportClicks = props => {
    return (
        <div className="reportClicks">
            <button onClick={props.dispatch(actions.myCustomReportingAction(props.clicks))}>Report {props.clicks} to the server</button>
        </div>
    )
}

const select = state => {
    return {
        clicks: extractProp(state.clicks)
    }
}

export default connect(select)(ReportClicks);
```

### Extracting values from segments using segmentConnect
Alternatively, you can simply use segmentConnect on your reporting component as well, and just assign both the CoolButton and reporting component the same `subscriberID`:

```javascript
<CoolButton subscriberID="coolClicks"/>
<ReportClicks subscriberID="coolClicks"/>

...

import React from 'react';
import { extractProp, segmentConnect } from 'redux-segmentize';

const actions = {
    myCustomReportingAction: clicks => ({ type: 'REPORT_CLICKS', amount: clicks })
}

const ReportClicks = props => {
    return (
        <div className="reportClicks">
            <button onClick={props.myCustomReportingAction(props.clicks)}>Report {props.clicks} to the server</button>
        </div>
    )
}

const select = state => {
    return {
        clicks: extractProp(state.clicks)
    }
}

export default segmentConnect(select)(ReportClicks, actions);
```<commit_msg>updating docs<commit_after># Redux Segmentize
By: <NAME>

Automatically manage component-based state with redux.

The recommended Container/Component setup is nice, but sometimes you need to re-use components throughout your app that need to manage their own state.  Setting up separate reducers for each instance of these components is a pain.  Now you can manage them automatically.  Set your reducer up once, then re-use it for each component instance.

### Installation
`npm install --save redux-segmentize`

### Step 1: Segmentize your Reducers
Build your reducers the way you would for managing just one instance, then wrap them like so with `segmentReducer()`:

```javascript
import { segmentReducer } from 'redux-segmentize';

function clicksReducer(state = 0, action) {
    switch(action.type) {
        case 'CLICK_COOL_BUTTON':
            return state + 1
    }

    return state;
}

const rootReducer = combineReducers({
    clicks: segmentReducer(clicksReducer),
    ...
});
```

### Step 2: Binding components to segmentized reducers
Build your components as you normally would.  Use `segmentConnect` instead of `react-redux`'s `connect`.  Segment connect detects which props are segments, then it sets up a new property within that segment where it can store values for the state of your component.  For example:

```javascript
import React from 'react';
import { segmentConnect } from 'redux-segmentize';

const CoolButton = props => {
    return (
        <div className="cool-button-component">
            <button>Push me</button>
            <div>Clicked { clicks } times.</div>
        </div>
    )
}

const select = state => {
    return {
        clicks: state.clicks
    }
}

export default segmentConnect(select)(BaseCounter);
```
Literally the only thing you need to change at this point is to use `segmentConnect` instead of `react-redux`'s `connect`.

### Step 3: Update segmentized state
Using normal actions can be a problem, since at this point, nothing will differentiate actions dispatched by each instance of `CoolButton`.  Once again, set up your actions as you normally would.  Then, instead of referencing them directly, you can inject them into your component's props via `segmentConnect`.  Then you can reference them from props.  

```javascript
import React from 'react';
import { segmentConnect } from 'redux-segmentize';

const actions = {
    click: () => ({ type: 'CLICK_COOL_BUTTON' })
}

const CoolButton = props => {
    return (
        <div className="cool-button-component">
            <button onClick={props.click()}>Push me</button>
            <div>Clicked { props.clicks } times.</div>
        </div>
    )
}

const select = state => {
    return {
        clicks: state.clicks
    }
}

export default segmentConnect(select)(BaseCounter, actions);
```

Notice, we've updated the onClick listener for the button.  Also, dispatch is automatically called for you.  In this case, executing the `click` function will dispatch your click event, appending a `subscriberID` attribute to the resulting object with the id of your component (it uses the `id` prop if available, otherwise it generates a unique identifier).  Your segmented reducer then applies that action to your reducer, storing the resulting value under your component's identifier, within your segment.  Your component also looks up that value with the same identifier.

Now you can simply use your component anywhere in your app, and it will automatically manage it's own state in Redux.  For example:

```javascript
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
<CoolButton />
etc.
```

Each instance of `CoolButton` has it's own place in your store, and fires it's own actions, all using the same code for your actions and reducer.

### Extracting values from segments, using normal components and react-redux
If you want another component to extract values from your segments (say, to make an AJAX request with), you can use the `extractProp` function.

First, you'll need to add a `subscriberID` prop (Alternatively `id` works as well) to your instance of `CoolButton` you want to report on.
```javascript
<CoolButton subscriberID="cool-button-1"/>
```

Next, let's set up the reporting component.

```javascript
import React from 'react';
import { extractProp } from 'redux-segmentize';
import { connect } from 'react-redux';

const actions = {
    myCustomReportingAction: clicks => ({ type: 'REPORT_CLICKS', amount: clicks })
}

const ReportClicks = props => {
    return (
        <div className="reportClicks">
            <button onClick={props.dispatch(actions.myCustomReportingAction(props.clicks))}>Report {props.clicks} to the server</button>
        </div>
    )
}

const select = state => {
    return {
        clicks: extractProp(state.clicks)
    }
}

export default connect(select)(ReportClicks);
```

### Extracting values from segments using segmentConnect
Alternatively, you can simply use segmentConnect on your reporting component as well, and just assign both the CoolButton and reporting component the same `subscriberID`:

```javascript
<CoolButton subscriberID="coolClicks"/>
<ReportClicks subscriberID="coolClicks"/>

...

import React from 'react';
import { extractProp, segmentConnect } from 'redux-segmentize';

const actions = {
    myCustomReportingAction: clicks => ({ type: 'REPORT_CLICKS', amount: clicks })
}

const ReportClicks = props => {
    return (
        <div className="reportClicks">
            <button onClick={props.myCustomReportingAction(props.clicks)}>Report {props.clicks} to the server</button>
        </div>
    )
}

const select = state => {
    return {
        clicks: extractProp(state.clicks)
    }
}

export default segmentConnect(select)(ReportClicks, actions);
```

### Dispatching Actions Manually Against Segmented State
If you want to dispatch actions outside of the context of a segmented component, there are 2 methods.

**Method 1**
Simply add subscriber ID to your actions

```javascript
const action = (some, stuff, subscriberID) => {
    return {
        type: 'SOME_TYPE',
        some,
        stuff,
        subscriberID
    }
}
```

**Method 2**
Wrap actions with the `segmentActions` or `segmentAction` convenience methods, so you don't have to pass subscriberID in every time.

```javascript
const action = (some, stuff) => {
    return {
        type: 'SOME_TYPE',
        some,
        stuff
    }
}

const wrappedAction = segmentAction(action, 'MySubscriberID');

...

store.dispatch(wrappedAction(123, 321));
```

```javascript
const actions = {
    action1: some => ({ type: 'SOME_EVENT' }),
    action2: thing => ({ type: 'ANOTHER_EVENT' })
}

const wrappedActions = segmentActions(actions, 'MySubscriberID');

store.dispatch(wrappedActions.action1(123))
store.dispatch(wrappedActions.action2(321))

```

### Flat(er) State Reducers
If you want to have a more flat state, and/or have a little more explicit control over your state structure, you can use `linkReducer` instead of `segmentReducer`.  `linkReducer` will only track one subscriberID, and thus will give you explicit control over it's contents.  Segmented components also know intuitively how to read linked reducers.

```javascript
const rootReducer = combineReducers({
    clicks: linkReducer(clicksReducer, 'MySubscriberID'),
    ...
});
```
{'fraction_non_alphanumeric': 0.09653126426289366, 'fraction_numerical': 0.002358131751102997, 'mean_word_length': 3.9129297458893872, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2575578', 'n_tokens_mistral': 3716, 'n_tokens_neox': 3516, 'n_words': 1443}