现有页面:
对应代码:
<li class={style.min_box}> <input class="" type="text" name="" id="" placeholder="输入牛号搜索" /> </li> |
希望实现的效果是:
当点击input输入框时,输入的内容有变化时,延迟一段时间(比如200ms),然后触发搜索接口,返回搜索出来的列表
reactjs input trigger search
jsx – Get the value input in the search box in reactjs – Stack Overflow
reactjs – React set focus on input after render – Stack Overflow
ReactJS: Input fire onChange when user stopped typing (or pressed Enter key)
react js input delay trigger search
jquery – Searching in React when user stops typing – Stack Overflow
javascript – Perform debounce in React.js – Stack Overflow
jquery – How to trigger an event in input text after I stop typing/writing? – Stack Overflow
Wait for User to Stop Typing, Using JavaScript | Gregory Schier
ReactJS : using debounce in react components
好像是我要的,但是:
react js debounce
nkbt/react-debounce-input: React component that renders Input with debounced onChange
threepointone/react-debounce: debounce as a component
然后去试试:
➜ ucowsapp git:(master) npm install –save react react-debounce-input npm WARN [email protected] requires a peer of react@^0.14.9 but none was installed. npm WARN [email protected] No repository field. npm WARN [email protected] No license field. added 3 packages, removed 34 packages and updated 1 package in 26.816s |
结果集成到已有页面中,是没有问题的
但是把输入搜索框封装后,移动到子模块中,结果就出问题了:
【不去解决】react-debounce-input调用出错:Uncaught TypeError Cannot read property apply of undefined
尝试去换用自己参考别人的timeout,去写代码:
但是试了半天,如果用timer的办法,虽然是可以的,但是onChange,只能在当输入了搜索内容后,光标离开输入框,才可以触发onChange -》 用户体验很不友好
timer的版本的代码如下:
import { h, Component } from ‘preact’; import style from ‘./style.less’; import PropTypes from ‘prop-types’; // import DebounceInput from ‘react-debounce-input’; import _ from "lodash"; export default class Search extends Component { state = { value : null } constructor(props) { super(props); this.timer = null; // this.debounceTimeout = this.props.debounceTimeout; this.onInputChange = this.onInputChange.bind(this); console.log(`Search constructor: this.props.placeholder=${this.props.placeholder},this.props.debounceTimeout=${this.props.debounceTimeout},this.props.onInputChange=${this.props.onInputChange}`); } componentWillMount() { console.log("Search componentWillMount"); this.timer = null; // this.delayedCallback = _.debounce(this.props.onInputChange, this.props.debounceTimeout); } componentWillUnmount() { console.log("Search componentWillUnmount"); console.log(this.timer); clearTimeout(this.timer); } onInputChange(e){ // onInputChange(newValue){ console.log("Search onInputChange"); console.log(e); console.log(this.timer); clearTimeout(this.timer); this.setState({value : e.target.value}); // this.setState({value : newValue}); this.timer = setTimeout( () => {this.props.onInputChange(this.state.value);}, this.props.debounceTimeout); console.log(this.timer); // e.persist(); // this.delayedCallback(e); } render () { return ( <div class={style.cz_top_box}> <ul> <a> <li class={style.min_box}> {/* <DebounceInput forceNotifyByEnter={false} forceNotifyOnBlur={false} debounceTimeout={this.props.debounceTimeout} placeholder={this.props.placeholder} onInputChange={this.onInputChange} /> */} <input type="search" value={this.state.value} placeholder={this.props.placeholder} onChange={this.onInputChange} /> </li> </a> </ul> </div> ); } } Search.PropTypes = { debounceTimeout : PropTypes.number, placeholder : PropTypes.string, onInputChange : PropTypes.func.isRequired }; Search.defaultProps = { debounceTimeout : 500, placeholder : "请输入后搜索" }; |
调用的方法:
/src/container/cow/cow-management/index.js
// onInputChange(e){ onInputChange(newValue){ console.log("CowManagement onInputChange"); // console.log(e); // console.log(e.target.value); // this.setState({ searchKeyword : e.target.value}); this.setState({ searchKeyword : newValue}); console.log(`this.state.searchKeyword=${this.state.searchKeyword}`); this.searchCowListByBlur(this.state.searchKeyword); } render() { return ( <div class={style.the_herd_all}> <Search placeholder="输入牛号搜索" onInputChange={this.onInputChange} /> |
再去试试,debounce的方式
componentWillMount() { console.log("Search componentWillMount"); // this.timer = null; this.delayedCallback = _.debounce(this.props.onInputChange, this.props.debounceTimeout); } // componentWillUnmount() { // console.log("Search componentWillUnmount"); // console.log(this.timer); // clearTimeout(this.timer); // } onInputChange(e){ // onInputChange(newValue){ console.log("Search onInputChange"); console.log(e); // console.log(this.timer); // clearTimeout(this.timer); this.setState({value : e.target.value}); // this.setState({value : newValue}); // this.timer = setTimeout( // () => {this.props.onInputChange(this.state.value);}, // this.props.debounceTimeout); // console.log(this.timer); e.persist(); this.delayedCallback(e.target.value); } |
但是不论是timer还是debounce,都还是基于onChange,都还是反应很慢的效果。
没有之前用的react-debounce-input,则光标没有离开输入框时,就可以触发onChange的调用了。
【已解决】ReactJS中input只有在光标离开失去焦点才能触发onChange
【总结】
最后使用了debounce的做法,完整代码为:
src/components/search/index.js
import { h, Component } from ‘preact’; import style from ‘./style.less’; import PropTypes from ‘prop-types’; import _ from "lodash"; export default class Search extends Component { state = { value : null } constructor(props) { super(props); this.onInput = this.onInput.bind(this); // console.log(`Search constructor: this.props.placeholder=${this.props.placeholder},this.props.debounceTimeout=${this.props.debounceTimeout},this.props.onInputChange=${this.props.onInputChange}`); } componentWillMount() { // console.log("Search componentWillMount"); this.delayedOnInput = _.debounce(this.props.onInputChange, this.props.debounceTimeout); } onInput(e){ // console.log((new Date()).Format("HH:mm:ss.S")); // console.log("Search onInputChange"); // console.log(e); this.setState({value : e.target.value}); e.persist(); this.delayedOnInput(this.state.value); } render () { return ( <div class={style.cz_top_box}> <ul> <a> <li class={style.min_box}> <input type="search" value={this.state.value} placeholder={this.props.placeholder} onInput={this.onInput} /> </li> </a> </ul> </div> ); } } Search.PropTypes = { debounceTimeout : PropTypes.number, placeholder : PropTypes.string, onInputChange : PropTypes.func.isRequired }; Search.defaultProps = { debounceTimeout : 500, placeholder : "请输入后搜索" }; |
调用的地方:
src/container/cow/cow-management/index.js
import Search from ‘../../../components/search’; onInputChange(currentValue){ // console.log("CowManagement onInputChange"); // console.log((new Date()).Format("HH:mm:ss.S")); this.setState({ searchKeyword : currentValue}); // console.log(`this.state.searchKeyword=${this.state.searchKeyword}`); this.searchCowListByBlur(this.state.searchKeyword); } render() { 。。。 return ( <div class={style.the_herd_all}> <Search placeholder="输入牛号搜索" onInputChange={this.onInputChange} /> 。。。 </div> ); } } |
效果:
即:
连续输入3次,对应的onInput会被调用,但是没有达到对应的500ms的间隔时间,则不会立刻调用,最后一次之后的500ms后,才会调用delayedOnInput-》onInputChange,然后触发搜索,返回结果。
转载请注明:在路上 » 【已解决】ReactJS中输入框输入内容变化时触发搜索返回列表