antd Select组件 filterOption使用踩坑报(options.props.children.toLower.Case() is not funcrion)

antd Select组件 filterOption使用

在使用antd Select组件的filterOption的踩坑。
如下是官网给出的示例:

                  <Select
                    showSearch
                    style={
    
    {
    
     width: 200 }}
                    placeholder="Select a person"
                    optionFilterProp="children"
                    filterOption={
    
    (input, option) =>{
    
    
                    console.log(input,option)                      option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                    }}
                  >
                    <Option value="jack">jack</Option>
                    <Option value="lucy">Lucy</Option>
                    <Option value="tom">Tom</Option>
                  </Select>

打印input,option结果如下图:
现在是很正常option.props.children的类型是string,使用indexOf,toLowerCase字符串的方法都没问题。但是一旦Option标签里显示值的前后有空格则option.props.children的类型则会成为array类型。这时如果使用了string的方法则会报错导致页面崩溃(请看代码片段1)。
官网示例打印结果
代码片段1如下:

<Select
                    showSearch
                    style={
    
    {
    
     width: 200 }}
                    placeholder="Select a person"
                    optionFilterProp="children"
                    filterOption={
    
    (input, option) =>{
    
    
                     console.log(input,option)
                      option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                    }}
                  >
                   //这里文本前后会有空格
                    <Option value="jack"> jack </Option>
                    <Option value="lucy"> Lucy </Option>
                    <Option value="tom"> Tom </Option>
                  </Select>

打印结果如下:
这里就需要注意children前后都有了空格(如果你用indexOf然后判断是否相等就会无结果,这个其实无伤大雅可以自己去除空格再做判断,但是如果你用变量形式children就会变成array,会造成崩溃,前提是你用了string的api).请看代码片段2
代码片段1输出结果
代码片段2:

const name="max" //这里需要注意如果变量本身存在空格则结果不会改变(cheildren打印结果" max ",这个时候也得去除空格再做操作) name=" max "
 <Select
                    showSearch
                    style={
    
    {
    
     width: 200 }}
                    placeholder="Select a person"
                    optionFilterProp="children"
                    filterOption={
    
    (input, option) =>{
    
    
                     console.log(input,option)
                      option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                    }}
                  >
                  //注意这里name前面多了空格 cheildren会变成['','max']
                  <Option value="tom"> {
    
    name}</Option>
                  </Select>

代码片段2打印结果:
**注意这里name为变量,前面多了空格 cheildren会变成[’ ',‘max’]**如果这时使用string 的api就会出现报错,导致页面崩溃。这里可以判断children类型做出不同的处理。
类型为string就让他用string Api.
类型为array就循环调用(先去除空项)string Api.

(Array.isArray(option.props.children) ? option.props.children.join('') : option.props.children).toLowerCase()
  filterOption = {(input, option) => {
        (Array.isArray(option.props.children) ? option.props.children.join('') : option.props.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
    }}

代码片段2打印结果

2021-11-17 补充

antd 4版本 也存在 这个 问题 所以也需要 判断一下 。区别就是 4.x版本 直接 options.children
3.x是 option.props.children.
4.x最好 把 return 也加上。

  filterOption = {(input, option) => {
       return  (Array.isArray(option.children) ? option.children.join('') : option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
    }}


这样写就不用加return。 上面的写法 是适用于 多行 ,也就是说你还可以写其它代码 。
下面这个 只能一句代码。

 filterOption = {
    
    (input, option) => 
       (Array.isArray(option.children) ? option.children.join('') : option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0
    }

antd 3.x select 带搜索 示例

<Select
    showSearch
    style={
    
    {
    
     width: 200 }}
    placeholder="Select a person"
    optionFilterProp="children"
    onChange={
    
    onChange}
    onFocus={
    
    onFocus}
    onBlur={
    
    onBlur}
    onSearch={
    
    onSearch}
    filterOption={
    
    (input, option) =>
      option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
    }
  >
    <Option value="jack">Jack</Option>
    <Option value="lucy">Lucy</Option>
    <Option value="tom">Tom</Option>
  </Select>

antd 4.x select 带搜索 示例

 <Select
    showSearch
    style={
    
    {
    
     width: 200 }}
    placeholder="Select a person"
    optionFilterProp="children"
    onChange={
    
    onChange}
    onFocus={
    
    onFocus}
    onBlur={
    
    onBlur}
    onSearch={
    
    onSearch}
    filterOption={
    
    (input, option) =>
      option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
    }
  >
    <Option value="jack">Jack</Option>
    <Option value="lucy">Lucy</Option>
    <Option value="tom">Tom</Option>
  </Select>

2021-11-18补充

还可能出现
TypeErro:Cannot resd property ‘toLowerCase’ of null at filterOption . 需要判断 值不为空的情况
这时就需要 加个判断 再使用 'toLowerCase

 filterOption = {
    
    (input, option) => 
       let val=(Array.isArray(option.children) ? option.children.join('') : option.children);
       return val?val.toLowerCase().indexOf(input.toLowerCase()) >= 0:null
    }

请添加图片描述
antd Select组件 Option里的值前后有空格则会出现崩溃现象,希望官方可以加入去除空格的操作

2021-12-16补充 select 赋值时的注意事项(类型要相同)

/*
这个案例 主要 是三个 sellect  主要体现了 select 设置 值时跟 类型也有 关系 类型 不对 也赋值不了。

一、是直接 赋值 "1"发现 默认值赋值上了
二、是声明了一个defaultVal 变量 赋值 为 number类型的 1 ,发现 默认值 未生效 
三、是声明了一个defaultVal2 变量 赋值 为 string类型的 1 ,发现 默认值 生效

结论 select的默认值 和赋值 时 需要 考虑 类型 必须全等才可以 赋值上
事实上 tree,treeSelect 都是如此 
*/
const {
    
     Select } = antd;

const {
    
     Option } = Select;

function handleChange(value) {
    
    
  console.log(`selected ${
      
      value}`);
}
let defaultVal=1; //类型数字 不能生效
let defaultVal2="1"; //类型 字符串 不能生效
ReactDOM.render(
  <div>
    <Select defaultValue="1" style={
    
    {
    
     width: 120 }} onChange={
    
    handleChange}>
      <Option value="1">Jack</Option>
      <Option value="2">Lucy</Option>
    </Select>

 <Select defaultValue={
    
    defaultVal} style={
    
    {
    
     width: 120 }} onChange={
    
    handleChange}>
      <Option value="1">Jack</Option>
      <Option value="2">Lucy</Option>
    </Select>

    <Select defaultValue={
    
    defaultVal2} style={
    
    {
    
     width: 120 }} onChange={
    
    handleChange}>
      <Option value="1">Jack</Option>
      <Option value="2">Lucy</Option>
    </Select>
  </div>,
  mountNode,
shihsi);

注意给 select 赋值时 类型要相等
antd select 赋值 的注意事项(必须类型相同才可以 在线演示
具体可看这篇博客:
antd select 赋值的注意事项,值赋不上的解决方案(必须类型相同才可以)
事实上 tree,treeSelect 都是如此

总结:

其实这个问题无伤大雅,都可以手动的避免。但是多个人协同开发,就会出现各种意想不到的问题(比如插件自己加空格,格式化,或者是疏忽了加了空格)。应该做好容错处理比如try catch等.但我还是希望官方可以做一些改动。
参考链接:
antd官网示例
antd github issues(遇到问题可以先找有咩有解决方案)

猜你喜欢

转载自blog.csdn.net/weixin_44058725/article/details/110520032#comments_22754776