'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
onBlur
instead ofonChange
so it will happen only when the user "leaves" the input - Use
debounce
like 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 |