I am trying to save a user's input by using the onChange method described here: https://facebook.github.io/react/docs/forms.html.
I have this line of code for my input:
<input type="text" onChange={this.changeTitle} ref="title" value={this.props.quiz ? this.getTitle() : ''}></input>
However, when I call this.refs.title.value after pressing the spacebar, the space is not registered. Is there anyway I can register this space?
Something as
var ChangeValue = React.createClass({
getInitialState() {
return { currentValue: '' };
},
onValueChange: function (evnt) {
this.setState({ currentValue: evnt.target.value });
},
render: function() {
return (
<div>
<input type="text" onChange={this.onValueChange} />
<p>
Current value is: <b>{this.state.currentValue}</b>
</p>
</div>
);
}
});
React.render(<ChangeValue />, document.body);
Just change onValueChange method to do what you need.
Live example: http://jsbin.com/xayowaloxa/edit?html,js,output
Related
I'm building a ReactJS search component for data filtering through search.
The idea is that the user types a word, letter after letter, and the system will filter all registers containing that word. The basic component is detailed below:
class SearchInput extends Component {
static propTypes = {
onKeyUp: PropTypes.func,
placeHolder: PropTypes.string,
value: PropTypes.string
};
state = {
searchText: ""
};
handleKeyUp = event => {
console.log(event.target.value) // <== No result. Always empty
let newSearchText = event.target.value;
this.setState({ searchText: newSearchText });
if (this.props.onKeyUp) this.props.onKeyUp(newSearchText);
};
render() {
console.log(this.state.searchText) // <== Always empty
return (
<div className="search-input">
<div className="search-input-icon">
<Icon name="faSearch" />
</div>
<input
autoFocus="true"
type="text"
onKeyUp={this.handleKeyUp}
placeholder={this.props.placeHolder}
value={this.state.searchText}
/>
</div>
);
}
I'm not getting the key pressed value on the handleKeyUp event handler.
It works if I ommit the value={this.state.searchText} (uncontrolled) from the code, but I need a way to set the searchText from outside the component (initialization, other component selection, etc.).
Why am I not getting the event.target.value data on my handler? How to fix it?
I'm pretty sure you have to listen to the onChange event on an input field to get the updated target value. simply change
<input onKeyUp={this.handleKeyUp} />
to
<input onChange={this.handleKeyUp} />
Try to use event.key instead.
The event.target.value just points to your this.state.searchText which hasn't been set yet.
seems you forgot to bind the function on the constructor:
class SearchInput extends Component {
constructor(props) {
super(props);
this.handleKeyUp = this.handleKeyUp.bind(this);
}
//... any code here
handleKeyUp = event => {
console.log(event.target.value);
}
render() {
//... any code here
<input
autoFocus="true"
type="text"
onKeyUp={this.handleKeyUp}
placeholder={this.props.placeHolder}
value={this.state.searchText}
/>
}
}
Use this:
let newSearchText = event.target.getAttribute('value')
I am trying to grab data only when user stops typing and remove cursor from input e.g onBlur along with when Up and down keys are pressed in React
var ExampleForm = React.createClass({
getInitialState: function () {
return {lastName: 1}
},
onsChange: function(event) {
this.setState({lastName: event.target.value});
},
render: function() {
return (<div>
<input name='lastName'
value={this.state.lastName}
type={"number"}
onChange={this.onsChange.bind(this)}/>
</div>
);
}
});
ReactDOM.render(
<ExampleForm/>,
document.getElementById('view'));
for remove cursor you have to use setTimeout. Do like this...
onsChange(event) {
this.setState({lastName: event.target.value});
var currentTarget = event.target;
setTimeout(function(){
currentTarget.blur();
}, 3000);
}
render() {
return (
<div>
<input name='lastName'
value={this.state.lastName}
type={"number"}
onChange={this.onsChange.bind(this)}/>
</div>
);
}
I am new to reactjs and trying to print update value of input field. What I firstly tried was this:
var App = React.createClass({
render() {
return <div>
<h1>Hello, {this.props.name}</h1>
<input type="text" onKeyUp={this.handleChange} />
<p>{this.handleChange}</p>
</div>;
},
handleChange: function(event) {
return event.target.value;
}
});
App = React.createFactory(App);
React.render(
<App name="World" />,
document.getElementById('mount-point'));
But I don't get it why it is not working. Than I tried this: CodePen maybe someone can help me with printing instantly the value of the input field in the <p> element
var App = React.createClass({
getInitialState: function() {
return {
text: "",
};
},
handleChange: function(event) {
this.setState({ text: event.target.value });
},
render() {
return <div>
<h1>Hello, {this.props.name}</h1>
<input type="text" onChange={this.handleChange} />
<p>{this.state.text}</p>
</div>;
},
});
You must store all state of the component in this.state. Use this.setState to update the state. When you update the state, the component is automatically rerendered with the new state.
The content of the paragraph is the current value of the state. onChange is commonly used instead of onKeyUp to handle changes of state in text inputs. handleChange will update the state when the text input changes.
I'am creating component with input element and button element.
I need to get the input value and use with button, for example. How can I do that?
Here's my code:
var InputSearch = React.createClass({
getInitialState: function() {
return {
value: 'pics'
}
},
handleChange: function() {
this.setState({
value: event.target.value
});
},
render: function() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange} />
)
}
});
var ButtonSearch = React.createClass({
handleClick: function(event) {
console.log(this.state.value); // here's go the input value
},
render: function() {
return (
<button onClick={this.handleClick}>GO! </button>
)
}
});
var Search = React.createClass({
render: function() {
return (
<div>
<InputSearch />
<ButtonSearch />
</div>
)
}
});
React.render(
<Search />,
document.getElementById('result')
);
One issue here is that you are breaking a good rule - separate smart and dumb components. https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
The way to do this is to have a parent component that holds all the state and functionality of the children and passes all of this down as props...
//Our smart parent
var SearchContainer = React.createClass({
getInitialState : function() {
return {
value : 'pics'
}
},
handleInput : function(event) {
this.setState({value: event.target.value});
},
render : function() {
return (
<div>
<InputSearch value={this.state.value} onChange={this.handleInput} />
<ButtonSearch value={this.state.value} />
</div>
)
}
});
//Our dumb children
var InputSearch = React.createClass({
propTypes : {
onChange : React.PropTypes.func.isRequired,
value : React.PropTypes.string
},
render : function() {
return (
<input type="text" value={this.props.value} onChange={this.props.onChange} />
)
}
});
var ButtonSearch = React.createClass({
propTypes : {
value : React.PropTypes.string
},
handleClick : function() {
console.log(this.props.value); //log value
},
render : function() {
return (
<button onClick={this.handleClick}>GO! </button>
)
}
});
React.render(<Search />, document.getElementById('result'));
Here we pass the handler function down from parent to child so the input doesn't care what happens to the event it fires on change, it just needs to know that it has a prop called onChange that's a function and it invokes that.
The parent (SearchContainer) handles all of that functionality and passes the changed state down to both the button and the input...
hope that helps
Dan
You left out the event in your handleChange.
handleChange: function(event) {
this.setState({
value: event.target.value
});
},
The main architecture of react is the Parent Child / Master Slave principle.
If you want to pass values between components you have to create relations between.
Like for example
You create your master Component with few default states.
var MyMasterComponent = React.createClass({
getInitialState: function(){
...
},
render: function(){
return(
<ChilComponent1 textiwanttopass={this.state.text} />
);
}
});
With that method you are calling the render of another component within a master component. That way you can pass values from states into another component.
In that case you can access the passed text with this.props.textiwanttopass
I have code that is at present accessing a React component directly, and getting a warning saying "You probably don't want to do this." The code is:
var description = document.getElementById('description').value;
console.log(description);
new_child.setState({
description: description
});
The component it's trying to access is:
var that = this;
return (
<table>
<tbody>
{that.state.children}
</tbody>
<tfoot>
<td>
<textarea className="description"
placeholder=" Your next task..."
onChange={that.onChange}
name="description"
id="description"></textarea><br />
<button onClick={that.handleClick}
id="save-todo">Save</button>
</td>
</tfoot>
</table>
);
What is an idiomatic way to replace the code I have here with a "thinking in React" replacement?
You should be using the refs attribute.
So lets say you have a render method that looks like this:
render: function () {
<MyTextBox ref="myText" />
<div>Some other element</div>
}
Now lets say the rendered MyTextBox element has a expode() method. You could call it using:
this.refs.myText.explode()
Essentially, refs has a property myText on it because during render, you provided a ref name to it by writing ref="myText"
You can find more info here
I'd call myself a complete novice here but looking at this code
https://github.com/abdullin/gtd/blob/master/web/components/TaskComposer.jsx
You should be able to bind to the textareas value:
<textarea id="description"
value={that.state.text} ...
and then you can pull out the value in your click handler like this:
var description = this.state.text;
Let me know if this works :)
UPDATE
Just looked at the React home-page (https://facebook.github.io/react/) and the 3rd example An Application seems to follow this pattern as well
var TodoList = React.createClass({
render: function() {
var createItem = function(itemText, index) {
return <li key={index + itemText}>{itemText}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [], text: ''};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});
React.render(<TodoApp />, mountNode);
So to answer you're question I think the React way to do stuff is to bind to this.state.