SO: Redux, basic form (React, JSX)

Redux, basic form (React, JSX)

by jonahe

HTML

<script src="https://unpkg.com/[email protected]/dist/react-with-addons.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.5/react-redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js"></script>
<div id="root"></div>

Babel + JSX

const {connect, Provider} = ReactRedux;
const {createStore, combineReducers} = Redux;

/*  REDUCER  */
const r1_initialState = { grains: [{grainId: "", amount: 0.0}] };
const reducer1 = (state = r1_initialState, action) => {
	switch(action.type) {
  	case CHANGE_GRAIN: 
    	const {index, key, newValue} = action;
    	const grainsCopy = [...state.grains];
      grainsCopy[index][key] = newValue;
    	return {...state, grains: grainsCopy};
      
    case ADD_EMPTY_GRAIN: {
    		return {...state, grains: [...state.grains, {grainId: '', amount: 0.0}]}
      }
    default: 
    	return state;
  }
};

/* ACTIONS */
const CHANGE_GRAIN = 'CHANGE_GRAIN';
const ADD_EMPTY_GRAIN = 'ADD_EMPTY_GRAIN';
const changeGrain = (index, key, newValue) => 
	({type: CHANGE_GRAIN, index, key, newValue});
const addEmptyGrain = () => ({type: ADD_EMPTY_GRAIN});

const store = createStore(
	combineReducers({reducer1})
);

class App extends React.Component {
	renderGrains() {
  	const {grains, changeGrain} = this.props;
  	return grains.map((grain, index) => (
        <div key={ index }>
          <input
            type="text" 
            value={grain.grainId} 
            onChange={({target:{value}}) => changeGrain(index, 'grainId', value)}
            />
          <input key={ grain.grainId + 'amount' }
            type="number" 
            value={grain.amount} 
            onChange={({target:{value}}) => changeGrain(index, 'amount', value)}
            /> 
          <br />
        </div>
      ));
  }
  render() {
  	const {addEmptyGrain, grains} = this.props;
    const onSubmit = (e) => {
    	e.preventDefault();
      alert('submitting: \n' + JSON.stringify({grains}, null, 2));
    };
		return (
    	<form>
        { this.renderGrains() }
        <button onClick={ (e) => { e.preventDefault(); addEmptyGrain();} }>Add grain</button><br />
        <button onClick={onSubmit}>Submit</button>
      </form>
    );
  }
}
const AppContainer = connect(
	(state, ownProps) => ({grains:...