I'm taking my first steps with React and I struggle with setting and getting states of an input
element.
- The application shall render a simple
input
element without a submit button. - When pressing Enter the current value of the text field shall be written to the console.
So far I've added two event handlers for onKeyUp
(checking if Enter was pressed) and another for onChange
to output the text field's value.
This is my current code:
import React, { Component } from "react";
import ReactDOM from "react-dom";
class Terminal extends React.Component {
constructor(props) {
super(props);
this.state = {value: ""};
this.handleChange = this.handleChange.bind(this);
}
handleKey(e) {
if (e.key === "Enter") {
console.log("Enter key pressed");
console.log(this.state.value);
}
}
handleChange(e) {
this.setState({value: e.target.value});
}
render() {
return (
<div>
<span>My Prompt: > </span>
<input type="text" value={this.state.value} onKeyUp={this.handleKey} onChange={this.handleChange} />
</div>
);
}
}
ReactDOM.render(
<Terminal />,
document.getElementById("root")
);
Pressing Enter is recognized but logging to the console gives me:
Uncaught TypeError: Cannot read property 'state' of undefined
at handleKey (index.js:24)
What am I missing here?
I'm taking my first steps with React and I struggle with setting and getting states of an input
element.
- The application shall render a simple
input
element without a submit button. - When pressing Enter the current value of the text field shall be written to the console.
So far I've added two event handlers for onKeyUp
(checking if Enter was pressed) and another for onChange
to output the text field's value.
This is my current code:
import React, { Component } from "react";
import ReactDOM from "react-dom";
class Terminal extends React.Component {
constructor(props) {
super(props);
this.state = {value: ""};
this.handleChange = this.handleChange.bind(this);
}
handleKey(e) {
if (e.key === "Enter") {
console.log("Enter key pressed");
console.log(this.state.value);
}
}
handleChange(e) {
this.setState({value: e.target.value});
}
render() {
return (
<div>
<span>My Prompt: > </span>
<input type="text" value={this.state.value} onKeyUp={this.handleKey} onChange={this.handleChange} />
</div>
);
}
}
ReactDOM.render(
<Terminal />,
document.getElementById("root")
);
Pressing Enter is recognized but logging to the console gives me:
Uncaught TypeError: Cannot read property 'state' of undefined
at handleKey (index.js:24)
What am I missing here?
Share Improve this question asked Nov 13, 2017 at 21:57 Robert StrauchRobert Strauch 12.9k32 gold badges143 silver badges231 bronze badges3 Answers
Reset to default 8You have 2 issues :
- You bound
handleChange
but you forgot to bindhandleKey
in the constructor .
Better is to not use manual binding , but to use arrow function instead.
handleKey = (e) => {
//....... ( See second issue )
}
handleChange = (e) => {
this.setState({value: e.target.value});
}
Second issue is how to know "enter" key is pressed . Use
const keyCode = e.keyCode || e.which; if (keyCode === 13) { // You code when "Enter" is pressed }
The demo below should work fine.
class Terminal extends React.Component {
// no need explicit constructor !
state = { value: '', cmds: [] };
handleKey = e => {
const keyCode = event.keyCode || event.which;
if (keyCode === 13) {
this.setState(({ cmds, value }) => ({
value: '',
cmds: [value, ...cmds]
}));
}
};
handleChange = e => {
this.setState({ value: e.target.value });
};
render() {
return (
<div>
<div>
<span>My Prompt: > </span>
<input
type="text"
value={this.state.value}
onKeyUp={this.handleKey}
onChange={this.handleChange}
/>
</div>
{this.state.cmds.map(cmd =>
<div>
{cmd}
</div>
)}
</div>
);
}
}
ReactDOM.render(<Terminal />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root" />
just change thease:
onChange={this.handleChange}
onKeyUp={this.handleKey}
to
onChange={this.handleChange = this.handleChange.bind(this)}
onKeyUp={this.handleKey = this.handleKey.bind(this)}`
You have to bind
the function to the context of the class.
<input type="text" value={this.state.value} onKeyUp={this.handleKey.bind(this)} onChange={this.handleChange.bind(this)} />