-
-
Save krambertech/76afec49d7508e89e028fce14894724c to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'; | |
import TextField from 'components/base/TextField'; | |
const WAIT_INTERVAL = 1000; | |
const ENTER_KEY = 13; | |
export default class TextSearch extends Component { | |
constructor(props) { | |
super(); | |
this.state = { | |
value: props.value | |
}; | |
} | |
componentWillMount() { | |
this.timer = null; | |
} | |
handleChange(value) { | |
clearTimeout(this.timer); | |
this.setState({ value }); | |
this.timer = setTimeout(::this.triggerChange, WAIT_INTERVAL); | |
} | |
handleKeyDown(e) { | |
if (e.keyCode === ENTER_KEY) { | |
::this.triggerChange(); | |
} | |
} | |
triggerChange() { | |
const { value } = this.state; | |
this.props.onChange(value); | |
} | |
render() { | |
const { className } = this.props; | |
return ( | |
<TextField | |
className={className} | |
placeholder={l('Search')} | |
value={this.state.value} | |
onChange={::this.handleChange} | |
onKeyDown={::this.handleKeyDown} | |
/> | |
); | |
} | |
} |
well done
Thank you
But I have modified some code. It works with my project.
import React, { Component } from 'react'
const WAIT_INTERVAL = 1000
const ENTER_KEY = 13
class TextSearch extends Component {
state = {
value: ''
}
timer = null
handleChange = e => {
clearTimeout(this.timer)
this.setState({ value: e.target.value })
this.timer = setTimeout(this.triggerChange, WAIT_INTERVAL)
}
handleKeyDown = e => {
if (e.keyCode === ENTER_KEY) {
clearTimeout(this.timer)
this.triggerChange()
}
}
triggerChange = () => {
const { value } = this.state
this.props.onChange(value)
}
render() {
const { ...rest } = this.props
return (
<input
type={rest.type}
className={rest.className}
placeholder={rest.placeholder}
value={this.state.value}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
/>
)
}
}
export default TextSearch
👍
@obbaeiei, you should clear timeout inside handleKeyDown
too. If your triggerChange
will do fetch to backend (via action creator if u use redux), you will see two requests after Enter pressed.
@0t3dWCE
I see. Thank you.
Thank you its work fine for me too
Any way to do this without this.setState({ value });
?
Because in reality a change is made in the local state immediately and then a props is dispatched to the parent component.
couldn't thank you enough for this, however I was wondering if there is any better way of doing the same.
Thank you
But I have modified some code. It works with my project.
import React, { Component } from 'react' const WAIT_INTERVAL = 1000 const ENTER_KEY = 13 class TextSearch extends Component { state = { value: '' } timer = null handleChange = e => { clearTimeout(this.timer) this.setState({ value: e.target.value }) this.timer = setTimeout(this.triggerChange, WAIT_INTERVAL) } handleKeyDown = e => { if (e.keyCode === ENTER_KEY) { clearTimeout(this.timer) this.triggerChange() } } triggerChange = () => { const { value } = this.state this.props.onChange(value) } render() { const { ...rest } = this.props return ( <input type={rest.type} className={rest.className} placeholder={rest.placeholder} value={this.state.value} onChange={this.handleChange} onKeyDown={this.handleKeyDown} /> ) } } export default TextSearch
Hey, can you explain what is type= rest.type attribute in input element.
Thank you
But I have modified some code. It works with my project.import React, { Component } from 'react' const WAIT_INTERVAL = 1000 const ENTER_KEY = 13 class TextSearch extends Component { state = { value: '' } timer = null handleChange = e => { clearTimeout(this.timer) this.setState({ value: e.target.value }) this.timer = setTimeout(this.triggerChange, WAIT_INTERVAL) } handleKeyDown = e => { if (e.keyCode === ENTER_KEY) { clearTimeout(this.timer) this.triggerChange() } } triggerChange = () => { const { value } = this.state this.props.onChange(value) } render() { const { ...rest } = this.props return ( <input type={rest.type} className={rest.className} placeholder={rest.placeholder} value={this.state.value} onChange={this.handleChange} onKeyDown={this.handleKeyDown} /> ) } } export default TextSearchHey, can you explain what is type= rest.type attribute in input element.
Never mind, got it, its the rest/spread thing you are using to pass the props passed to the component.
Thanks again.
Thank you
But I have modified some code. It works with my project.
import React, { Component } from 'react' const WAIT_INTERVAL = 1000 const ENTER_KEY = 13 class TextSearch extends Component { state = { value: '' } timer = null handleChange = e => { clearTimeout(this.timer) this.setState({ value: e.target.value }) this.timer = setTimeout(this.triggerChange, WAIT_INTERVAL) } handleKeyDown = e => { if (e.keyCode === ENTER_KEY) { clearTimeout(this.timer) this.triggerChange() } } triggerChange = () => { const { value } = this.state this.props.onChange(value) } render() { const { ...rest } = this.props return ( <input type={rest.type} className={rest.className} placeholder={rest.placeholder} value={this.state.value} onChange={this.handleChange} onKeyDown={this.handleKeyDown} /> ) } } export default TextSearch
Thanks
👍
Initialise
this.timer in constructor instead of lifecycle
constructor( ) {
super()
this.timer = null
}
I am trying to make an API call. But, as soon as I am writing some in the textbox. I am getting "Uncaught TypeError: this.props.onChange is not a function at TextSearch.triggerChange ". Thanks.
Would be great if someone will put the same example but with react hook (for react component) example.
Hi
For react hook I found this great article :
Frédérik
👍
Great share ! Thank you 👍
I did the update told by @barsbek and also added a "searchChanged" boolean so there's no useless API call if the user frantically taps Enter.
handleChange(e) {
clearTimeout(this.timerId);
this.setState({ search: e.target.defaultValue });
this.searchChanged = true;
this.timerId = setTimeout(this.updateList, SearchFolder.WAIT_INTERVAL);
}
handleKeyDown(e) {
if (e.keyCode === SearchFolder.ENTER_KEY && this.searchChanged) {
clearTimeout(this.timerId);
this.updateList();
}
}
updateList() {
this.searchChanged = false;
this.repository.peek(this.state.search, 0, 15, 0).then((response: FolderListItem[]) => {
this.setState({ listItems: response });
}).catch((error) => {
this.setState({ item: "Erreur : " + error.message });
});
}
Thanks! Really helpful!