React输入拼音触发搜索

950 阅读2分钟

在打造search组件时会经常使用到input组件,但这有一个就是当用户输入拼音时便触发搜索功能有时候这并不是我们想要的。

假入有如下Input组件

import React, { Component } from "react";

export default class Input extends Component {
    onChange = (e) => {
        this.props.onChange(e.target.value);
    };
    render() {
        const { value } = this.props;
        return (
            <div
                style={{
                    border: "2px solid blue",
                    padding: "10px",
                }}
            >
                <h3>input组件</h3>
                <input onChange={this.onChange} value={value} />
            </div>
        );
    }
}

有如下search组件

import React, { useState } from "react";
import Input from "./Input";

function Search() {
   const [value, setValue] = useState("");
   return (
       <>
           <h2>Search组件</h2>
           <Input onChange={setValue} value={value} />
           <div style={{ marginTop: "100px" }}>{value}</div>
       </>
   );
}

export default Search;

运行结果如下 截屏2021-03-13 17.44.45.png

很明显输入的拼音也别带过来了,这样就会触发搜索

compositionstart,compositionend

这时候就需要引入我们的 compositionstart,compositionend,这两个都是input身上的函数,可以理解为其身上的生命周期函数,会在新的输入合成时调用,详细可在百度上自己查询。我只需要在外部定义一个变量用于监听输入的状态,在我输入拼音时为false输入完成变为true。 修改Input组件代码 写完代码再到浏览器查看居然连拼音都输入不了了!!!

如何解决

为什么会出现这种情况??? 因为我们input的value值依赖于props中的value,我们禁止了拼音的输入导致input接收不到拼音也就无法显示了。

思路:

在state中设置一个临时变量用于显示用户的输入,而传输给Search组件的是没有拼音的部分,这个临时变量在用户拼音输入完成时和用户在search中的输入保持一致,这时候就需要getDerivedStateFromProps这个生命周期函数来控制state中的value。修改后的Input组件代码如下:

import React, { Component } from "react";

export default class Input extends Component {
  static getDerivedStateFromProps(props, state) {
      if (props.value !== state.prevPropsValue) {
          return {
              value: props.value,
              prevPropsValue: props.value,
          };
      }
      return null;
  }

  static flag = true;

  state = {
      value: this.props.value,
      prevPropsValue: this.props.value,
  };

  onChange = (e) => {
      if (this.flag) {
          this.props.onChange(e.target.value);
      } else {
          this.setState({
              value: e.target.value,
          });
      }
  };
  onCompositionStart = () => {
      this.flag = false;
  };
  onCompositionEnd = (e) => {
      this.flag = true;
      this.props.onChange(e.target.value);
  };
  render() {
      return (
          <div
              style={{
                  border: "2px solid blue",
                  padding: "10px",
              }}
          >
              <h3>input组件</h3>
              <input
                  onChange={this.onChange}
                  value={this.state.value}
                  onCompositionStart={this.onCompositionStart}
                  onCompositionEnd={this.onCompositionEnd}
              />
          </div>
      );
  }
}

最终结果如下

截屏2021-03-13 18.48.55.png

如果有问题欢迎指出 :)