最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】ReactJS中输入框输入内容变化时触发搜索返回列表

ReactJS crifan 4079浏览 0评论

现有页面:

对应代码:

              <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

How to "onchange" in ReactJS

ReactJS: Input fire onChange when user stopped typing (or pressed Enter key)

enkidevs/react-search-input: Simple react.js component for a search input, providing a filter function.

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

好像是我要的,但是:

【已解决】JS中什么是debounce

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中输入框输入内容变化时触发搜索返回列表

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.163 seconds, using 22.11MB memory