I have made a small app in React that fulfils the following user stories:
GIVEN I add an item using the form
THEN I see the text appear in the list below
GIVEN I see items in the list
AND I click the close button next to a list item
THEN the list item disappears from the page
GIVEN I refresh the page at any point
THEN I see the list that I saw on the page before I refreshed
Here is my code:
const TodoInput = props => {
return (
<form>
<div>Enter a todo</div>
<input
type="text"
onChange={props.onHandleChangeInputVal}
value={props.inputVal}
/>
<button
type="submit"
onClick={props.onHandleAddTodo}
>
Add to the list
</button>
</form>
)
};
class TodosList extends React.Component {
constructor() {
super();
this.state = {
inputVal: '',
todos: []
};
this.onHandleChangeInputVal = this.onHandleChangeInputVal.bind(this);
this.onHandleAddTodo = this.onHandleAddTodo.bind(this);
}
componentDidMount() {
const todosFromLocalStorage = JSON.parse(localStorage.getItem('localStorageTodos'));
this.setState({
todos: todosFromLocalStorage || []
})
}
getTodos() {
const todos = this.state.todos;
return todos.map((todo, index) => {
return (
<li
key={index}
>
{todo}
<button onClick={event => this.onHandleDeleteTodo(event, index)}>×</button>
</li>
)
})
}
onHandleChangeInputVal(e) {
const newInputVal = e.target.value;
this.setState({
inputVal: newInputVal
})
}
onHandleAddTodo(e) {
e.preventDefault();
let todosCopy = this.state.todos.slice();
if (this.state.inputVal) {
todosCopy.push(this.state.inputVal);
}
this.setState({
todos: todosCopy,
inputVal: ''
}, () => {
this.updateLocalStorageWithState();
});
}
onHandleDeleteTodo(event, indexOfItemToRemove) {
event.preventDefault();
let todosCopy = this.state.todos.slice();
todosCopy.splice(indexOfItemToRemove, 1);
this.setState({
todos: todosCopy
}, () => {
this.updateLocalStorageWithState();
});
}
updateLocalStorageWithState() {
localStorage.setItem('localStorageTodos', JSON.stringify(this.state.todos));
}
render() {
const todos = this.getTodos();
return (
<div>
<TodoInput
onHandleChangeInputVal={this.onHandleChangeInputVal}
onHandleAddTodo={this.onHandleAddTodo}
inputVal={this.state.inputVal}
/>
<ul>{todos}</ul>
</div>
)
}
}
ReactDOM.render(<TodosList />, document.getElementById('app'));
Here is a demo: http://codepen.io/alanbuchanan/pen/RoKBLr?editors=0010
Please can you review for any improvements to how I have structured and written my code?