taro input onInput 值不更新的原因,表单组件不是受控组件

1,573 阅读1分钟

大家好,我是小十七_,今天一起来看一个 taro 表单组件的问题,taro input onInput 值不更新的原因,表单组件不是受控组件

遇到的问题

一天,产品提了一个很简单的需求,一个输入框只能输入字母,本来以为 input 肯定是受控组件,分分钟搞定,没想到搞了半天

代码是这样的:

import React, { useState } from 'react';
import { Input } from '@tarojs/components';

export default function Test() {
  const [value, setValue] = useState('');
  const handleInput = e => {
    setValue(e.detail.value.replace(/[^a-zA-Z]/g, ''));
  };

  return <Input value={value} onInput={handleInput} maxlength={6} />;
}

本来以为这就结束了,结果测试后,没有生效

  • 输入 a,显示 a
  • 输入 a1,显示 a1

可以发现 input 不是一个受控组件,输入 a1 后,我们在 onInput 中改了 state 中的 value 为 a,并没有更新到 input 中。

原因 & 解决方式

参考这个回答:github.com/NervJS/taro…

微信小程序中表单组件不是完全受控的,Input 组件输入后,视图立即变化,但其 value 绑定的值还是旧值,这时你直接 setState 一个旧值会被 Taro 的 diff 过滤掉。

发现 Taro 的 官方文档 已经写了这个问题,和一些其他问题的解决方法

具体的过程是: 输入 a。 视图显示 a。 onInput 逻辑处理后 setState({ val: 'a' }) taro diff('a', '') setData({ val: 'a' })

输入 1。 视图显示 a1。 onInput 逻辑处理后 setState({ val: 'a' }) taro diff('a', 'a') 不去 setData

解决的办法在于视图改变时,立即同步 data,把值改成新值,然后再对 data 值进行进一步修改。

const handleInput = e => {
    setValue(e.detail.value);
    setTimeout(() => setValue(e.detail.value.replace(/[^a-zA-Z]/g, '')))
  };

参考