title: Sharing actions and reducers with react/redux
body: <p>I'm still very much a react/redux noob. On one page I have a ton of text inputs. After a while I started noticing my action file has functions doing the same thing but for different inputs:</p>
  
  <pre><code>export function setInputName(string) {
    return {
      type: 'SET_CURRENT_NAME',
      payload: {value: string}
    };
  }
  export function setInputCity(string) {
    return {
      type: 'SET_CURRENT_CITY',
      payload: {value: string}
    };
  }
  </code></pre>
  
  <p>With my reducer looking like:</p>
  
  <pre><code>export function currentName(state='', {type, payload}) {
    switch (type) {
    case 'SET_CURRENT_NAME':
      return payload.value;
    default:
      return state;
    }
  }
  export function currentCity(state='', {type, payload}) {
    switch (type) {
    case 'SET_CURRENT_CITY':
      return payload.value;
    default:
      return state;
    }
  }
  </code></pre>
  
  <p>And my component had these multiple inputs:</p>
  
  <pre><code>import {Component, PropTypes} from 'react';
  import {connect} from 'react-redux';
  import {bindActionCreators} from 'redux';
  import {setInputName, setInputCity} from 'actions/form';
  
  export default class Form extends Component {
    static propTypes = {
      setInputName: PropTypes.func.isRequired,
      setInputCity: PropTypes.func.isRequired,
      currentName: PropTypes.string.isRequired,
      currentCity: PropTypes.string.isRequired
    }
    render() {
      let {setInputName, setInputCity, currentName, currentCity} = this.props;
      return (
        &lt;div&gt;
          &lt;input
            type="text" 
            placeholder="Name"
            onChange={(e) =&gt; setInputName(e.currentTarget.value)}
            value={currentName}
          /&gt;
          &lt;input
            type="text" 
            placeholder="City"
            onChange={(e) =&gt; setInputCity(e.currentTarget.value)}
            value={currentCity}
          /&gt;
        &lt;/div&gt;
      );
    }
  }
  
  function select(state) {
    return {
      currentName: state.form.currentName,
      currentCity: state.form.currentCity
    };
  }
  
  function actions(dispatch) {
    return bindActionCreators({
     setInputName: setInputName,
     setInputCity: setInputCity,
    }, dispatch);
  }
  
  export default connect(select, actions)(Form);
  </code></pre>
  
  <p>Which isn't very DRY and I immediately thought I was doing something wrong. Is there a good way to have a common <code>setInputValue</code> action for all text inputs on every page and component of my app? I would also want to use a common reducer for every input. Thank you.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Here's my gross example that works but I feel like this is still a bit convoluted and there has to be a better way. Basically in the reducer I check to see if that input has been used and added to the state yet. If not I add it. If so I just update its value. <strong>EDIT</strong> I lied this doesn't actually work.</p>
  
  <pre><code>// actions
  export function updateTextInput(name, value) {
    return {
      type: 'SET_CURRENT_TEXT_INPUT',
      payload: {name: name, value: value}
    };
  }
  
  // reducer
  export function currentTextInput(state=[], {type, payload}) {
    switch (type) {
    case 'SET_CURRENT_TEXT_INPUT':
      let newState = state;
      let curInput = state.findIndex(function(elem) {
        return elem.name === payload.name;
      });
      if (curInput === -1) {
        newState.push({name: payload.name, value: payload.value});
      } else {
        newState[curInput].value = payload.value;
      }
      return newState;
    default:
      return state;
    }
  }
  
  // component
  ...
  render() {
    let {updateTextInput, currentTextInput} = this.props;
    return (
      &lt;div&gt;
        &lt;input
          type="text" 
          placeholder="Name"
          onChange={(e) =&gt; updateTextInput('name', e.currentTarget.value)}
          value={currentTextInput.name}
        /&gt;
        &lt;input
          type="text" 
          placeholder="City"
          onChange={(e) =&gt; updateTextInput('city', e.currentTarget.value)}
          value={currentTextInput.city}
        /&gt;
      &lt;/div&gt;
    );
  }
  ...
  </code></pre>