Please critique my TODO App in React w/ Redux:
// React Component const TodoApp = ({todos, inputText, onInputChange, onAdd, onDelete}) => { const numbers = range(todos.length); const zipped = zip(numbers, todos); return ( <div> <h1>TODO!</h1> <ul>{zipped.map( (z) => <li key={z[0].toString()}> {z[1].text} <button onClick={() => onDelete(z[0])}>delete</button> </li> )} <li> <input type="text" value={inputText} onChange={onInputChange}/> <button onClick={onAdd}>add</button> </li> </ul> </div> ); }; // Redux (State) const ADD = 'ADD'; const UPDATE_INPUT_TEXT = 'UPDATE_INPUT_TEXT'; const DELETE='DELETE'; function todo(state = {todos: [], inputText: ""}, action) { switch(action.type) { case ADD: return { todos: state.todos.concat( { text: state.inputText }), inputText: '' }; case UPDATE_INPUT_TEXT: return { todos: state.todos, inputText: action.newInputText }; case DELETE: const filtered = state.todos.filter( (e, index) => index !== action.index); return { todos: filtered, inputText: '' }; default: return state; } } const store = createStore(todo); const renderTodo = () => { const st = store.getState(); ReactDOM.render( <TodoApp todos={st.todos} inputText={st.inputText} onInputChange={event => store.dispatch({type: UPDATE_INPUT_TEXT, newInputText: event.target.value}) } onAdd={() => store.dispatch({type: ADD})} onDelete={(index) => store.dispatch({type: DELETE, index: index})} />, document.getElementById('root') ) }; store.subscribe(renderTodo); renderTodo();