Reputation: 57
import React, { Component, createElement } from "react";
export default class TodoList extends Component {
handleKeyDown = (e) => {
if (e.keyCode === 13) {
console.log("enter has been pressed");
}
};
handleChange = (e) => {
console.log("something has occurred");
};
render() {
return (
<div className="container">
<h1 className="heading">Todo List</h1>
<div className="list">No todos.</div>
<input
type="text"
className="insertTodo"
placeholder="Add a new todo!"
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
value={this.state.inputValue}
/>
</div>
);
}
}
I can't seem to type into the input which is why handleChange
isn't getting called. Am I doing something wrong? handleKeyDown
is working fine, logging to the console when the enter
key is pressed.
Thanks!
Upvotes: 0
Views: 47
Reputation: 13245
func = (e) => {...}
, you say func(e) {...}
bind
the this
context to each class functione.preventDefault()
which prevented handleChange()
from being calledhttps://jsfiddle.net/4vs685u1/1/
class TodoList extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ""
}
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleKeyDown(e) {
if (e.keyCode === 13) {
console.log("enter has been pressed");
}
}
handleChange(e) {
console.log("something has occurred");
this.setState({
inputValue: e.target.value
})
}
render() {
return (
<div className="container">
<h1 className="heading">Todo List</h1>
<div className="list">No todos.</div>
<input
type="text"
className="insertTodo"
placeholder="Add a new todo!"
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
value={this.state.inputValue}
/>
</div>
);
}
}
ReactDOM.render(<TodoList />, document.querySelector("#root"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
If you're just now learning React, I would recommend using Functional Components with Hooks. The syntax is a lot more straight forward:
const TodoList = () => {
const [inputValue, setInputValue] = React.useState("");
const handleKeyDown = (e) => {
if (e.keyCode === 13) {
console.log("enter has been pressed");
}
}
const handleChange = (e) => {
console.log("something has occurred");
setInputValue(e.target.value);
}
return (
<div className="container">
<h1 className="heading">Todo List</h1>
<div className="list">No todos.</div>
<input
type="text"
className="insertTodo"
placeholder="Add a new todo!"
onChange={handleChange}
onKeyDown={handleKeyDown}
value={inputValue}
/>
</div>
);
}
ReactDOM.render(<TodoList />, document.querySelector("#root"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
Upvotes: 1
Reputation: 168
I to give an answer to clarify some of the things that were raised in the comments which are related to the way you functions work.
Now first of all you cannot type into the input because you are using controlled inputs and you do not set the state of your input, therefor your input value will always be the value you set as default in the state.
constructor(props) {
super(props);
this.state = { inputValue: "" };
}
So all you have to do is set the state when the input changes
handleChange = (e) => {
this.setState({ ...this.state, inputValue: e.target.value })
console.log("something has occurred");
};
The second thing that was mentioned in comments is that you do not use proper syntax for functions, and that was a reference that in class components you usually have to bind the this
keyword to the class itself. In your case however because you are using arrow functions, the this
keyword is set the the lexical scope of where the function was defined there for this
is already set to the class itself. So there is no need to bind it.
Upvotes: 1
Reputation: 4519
You need to bind your methods. From the docs:
If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
import React, { Component, createElement } from "react";
export default class TodoList extends Component {
constructor(props){
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleChange = this.handleChange.bind(this)
}
// The rest of your component code here...
}
}
Also, using arrow functions like you're doing is "experimental syntax" in React. You should consider either using function components or changing you function declaration to a non arrow function:
handleChange(e) => {
console.log("something has occurred");
};
More info: https://reactjs.org/docs/handling-events.html
Upvotes: 1