'Recommendations to get React input test
What is the most efficient way to get the text in an input?
I know I can have it like this
handleChange = (event) => {
this.setState({[event.target.name]: event.target.value});
};
<Input onChange = {this.handleChange}/>
Wouldn't this cause performance issues since I'm updating the state (which causes a rerender) every time a change is made to the input? Should I write a shouldComponentUpdate method to stop it from rerendering?
Also, is there a way to get what is inside the Input only when a button is clicked?
Solution 1:[1]
You have some options:
- Use
onBlurinstead ofonChangeso it will happen only when the user "leaves" the input - Use
debouncelike this one.
But it depends on the experience and the ui impact of that change. I mean, if you need immediate impact (you present the value somewhere else in the UI), I don't think you have a choice.
If not, and you case is standart form (or form like), you can listen to onSubmit and extract the values from the form, something like this:
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
onSubmit = (e) => {
e.preventDefault();
const values = Array.from(e.target.elements).reduce((old, current) => {
if (current.attributes.name) {
old[current.name] = current.value
}
return old;
}, {})
this.setState(values);
}
render() {
return (
<>
<form onSubmit={this.onSubmit}>
<input name="name" placeholder="name" />
<input name="email" placeholder="email" />
<button>Submit</button>
</form>
<hr />
<pre>
{
JSON.stringify(this.state, null, 2)
}
</pre>
</>
);
}
}
Solution 2:[2]
You can use react refs or use one of the UI libraries like ant-design to have better input and form management.
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
Solution 3:[3]
Yes, every keypress will change the state and will re-render the component.
But, as react compares the virtually created DOM before rendering, it will only re-render the Input field to browser in your case.
If you want to avoid that too, You should create small small components extending from PureComponent. PureComponent implements shouldComponentUpdate internally. That way it will re-render only Input field leaving other components as it is.
Solution 4:[4]
You can use ref to get value of Input. Here is example how you can do it. I have added to get value and to clear value
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
}
getValue = () => {
console.log(this.textInput.value)
}
clearValue = () => {
this.textInput.value = ""
}
render() {
return (
<div>
<input
type="text"
ref={el => this.textInput = el}
/>
<input
type="button"
value="Get Value"
onClick={this.getValue}
/>
<input
type="button"
value="Clear Value"
onClick={this.clearValue}
/>
</div>
);
}
}
export default CustomTextInput;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mosh Feu |
| Solution 2 | Afsanefda |
| Solution 3 | Ashish |
| Solution 4 | Harish |
