Filth Filth - 1 month ago 9
React JSX Question

React JS To do list app | Get value and push to state

I'm building a to do list application which is taking in two objects from a store set as default.

Having trouble taking what the user has inputted as their new "to do" item and pushing it to the store / application state.

If I click on the "Create new" button, this successfully creates a new to do item however, no text.

I am getting the value from the input with the handleChange function - I need to send that value as part of the createTodo function to the store.

The createToDo function is what calls the action to add a new "to do" item to the store. I can't figure out how to tie the input value to that function to create the new to do item.

Here is my code so far:

import React from "react";

import Todo from "../components/Todo";
import * as TodoActions from "../actions/TodoActions";
import TodoStore from "../stores/TodoStore";


export default class Featured extends React.Component {
constructor() {
super()
this.getTodos = this.getTodos.bind(this);
this.state = {
todos: TodoStore.getAll()
}
}

componentWillMount() {
TodoStore.on("change", this.getTodos);
console.log("count", TodoStore.listenerCount("change"));
}

componentWillUnmount() {
TodoStore.removeListener("change", this.getTodos);
}

getTodos() {
this.setState({
todos: TodoStore.getAll(),
});
}

createTodo(text) {
TodoActions.createTodo();
}

handleChange(e) {
let text = e.target.value;
console.log(text);
}

reloadTodos() {
TodoActions.reloadTodos();
}


render() {
const { todos } = this.state;

console.log("todos", todos);

const todoitems = todos.map((todoitem) => {
return <Todo key={todoitem.id} {...todoitem} />
});

return (
<div className="todolist-wrapper">
<h1>To do list</h1>
<button onClick={this.reloadTodos.bind(this)}>Reload</button>
<ul>
{todoitems}
</ul>
<input type="text" onChange={this.handleChange.bind(this)} />
<button onClick={this.createTodo.bind(this)}>Create new</button>
</div>
);
}
}

Answer

First add the value to your component's state:

constructor() {
  ...
  this.state = {
    todos: TodoStore.getAll(),
    value: ""
  }
}

You can add this as the value attribute of the input element itself (in order to let the initial value within your state control the initially-rendered value of the input element):

<input type="text" value={this.state.value} onChange={this.handleChange.bind(this)} />

Then in your handleChange function, modify the state's value using setState:

handleChange(e) {
  let text = e.target.value;
  this.setState({
    value: text
  });
}

Now you can grab the value from your component's state within your createTodo function:

createTodo() {
  let text = this.state.value;
  TodoActions.createTodo(text);
}