React+Antd Form控件前后加文案或样式后不能获取到值问题+手写校验输入字符(包含中文)长度

React+Antd Form控件前后加文案或样式后不能获取到值问题+手写校验输入字符(包含中文)长度,第1张

文章目录 问题一:控件前后加元素获取值引入解决方案 问题二:手写校验解决

问题一:控件前后加元素获取值 引入

当使用Form.Item时,内部包含Select选择框,但由于需求,需要在Select前加一个 “*” 样式装点。

这个时候会导致使用form的name属性时:getFieldValue('country')无法读取到值(见下图),因为form不仅仅是只包含了Select框元素。

原代码(效果未实现):

	<Form.Item label="地区" name="country" key="country">
          <span className={Styles.specialrequired} style={{ transform: 'translate(-60px, 4px)'}}> 
            *
          </span>
          <Select
            showSearch
            style={{ width: 150 }}
            dropdownMatchSelectWidth={false}
            placeholder="请选择地区"
            value={selectCountry}
            onChange={e => setSelectCountry(e)}
          >
            {countryList?.map(e => (
              <Select.Option
                key={e.name}
                value={e.value}
              >
                {e.name}
              </Select.Option>
            ))}
          </Select>
	</Form.Item>

当地区改变时,country值一直为undefined,未获取状态。


解决方案

修改后代码:

	<Form.Item label="地区">
          <span className={Styles.specialrequired} style={{ transform: 'translate(-60px, 4px)'}}>
            *
          </span>
          <Form.Item name="country" key="country" noStyle>
            <Select
              showSearch
              style={{ width: 150 }}
              dropdownMatchSelectWidth={false}
              placeholder="请选择地区"
              value={selectCountry}
              onChange={e => setSelectCountry(e)}
            >
              {countryList?.map(e => (
                <Select.Option
                  key={e.name}
                  value={e.value}
                  disabled={!_.some(region, item => item.name === e.name)}
                >
                  {e.name}
                </Select.Option>
              ))}
            </Select>
          </Form.Item>
    </Form.Item>

再去看Antd官方文档解释:

如果控件前后还有一些文案或样式装点,或者一个表单项内有多个控件,应使用内嵌的 Form.Item 完成。
你可以给 Form.Item 自定义 style 进行内联布局,或者添加 noStyle 作为纯粹的无样式绑定组件

意思可以类比于div盒子,当控件中有多个控件或元素时,需要将最外层的Form.Item作为布局加上label属性,给里面的每个需要获取的控件再包裹一次Form.Item并且给上name属性.

注意,在 label 对应的 Form.Item 上不要在指定 name 属性,这个 Item 只作为布局作用。

问题二:手写校验

要求输入的字符不能超过64个字符,且不包含特殊字符。

注意是字符而不是字符串长度,所以不能使用antd自带的min和max规则判断字符串的length。

字符长度(错误):不能正确校验中文

{ type: 'string', min: 0, max: 64, message: '任务名称必须在0-64字符内!' },

对字符串进行处理,将中文处理未双字节 后再取长度进行判断

解决

在Form.item中加上rules属性,并手写校验规则,建议把所有校验规则条件写在此处,可以控制条件校验的先后顺序

此处先校验是否包含特殊字符,当不包含特殊字符时才校验任务名称的字符长度

rules={[
         {
           validator(_, value) {
           const pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]",
                  )
                  if (pattern.test(value)) {
                    return Promise.reject(new Error('任务名称不允许包含特殊字符'))
                  }
                  if (value.replace(/[\u4e00-\u9fa5]/g, 'aa').length > 64) {
                    return Promise.reject(new Error('任务名称不能超过64个字符'))
                  }
                  return Promise.resolve()
                },
              },
]}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1296962.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存