From 5b1002adfd8202a0f218fd32ccb33d53dfc1ea91 Mon Sep 17 00:00:00 2001 From: colder Date: Sat, 13 Jun 2020 22:18:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20Textarea=20?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E8=BE=93=E5=85=A5=E6=B3=95=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E9=80=A0=E6=88=90=20onChange=20=E4=B8=8D=E6=8A=A5=E6=88=96?= =?UTF-8?q?=E8=AF=AF=E6=8A=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Textarea.tsx | 12 ++++----- src/TextareaEnhance.tsx | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/TextareaEnhance.tsx diff --git a/src/Textarea.tsx b/src/Textarea.tsx index 040cc1b..c0e3d8e 100644 --- a/src/Textarea.tsx +++ b/src/Textarea.tsx @@ -1,14 +1,14 @@ -import React, { useRef, useMemo } from 'react' +import React, { useMemo } from 'react' import Taro from '@tarojs/taro' import classNames from 'classnames' -import { View, Textarea as _Textarea, CommonEventFunction } from '@tarojs/components' -import { TextareaProps as _TextareaProps } from '@tarojs/components/types/Textarea' +import { View, CommonEventFunction } from '@tarojs/components' import { AtTextareaProps } from 'taro-ui/types/textarea' +import { TextareaEnhance, TextareaEnhanceProps } from './TextareaEnhance' import '../style/Textarea.scss' export interface TextareaProps - extends Omit<_TextareaProps, 'className' | 'value' | 'focus' | 'onInput'>, + extends Omit, Pick { className?: string style?: React.CSSProperties @@ -57,19 +57,17 @@ export const Textarea: React.FC = (props) => { return ( - <_Textarea + {count && ( diff --git a/src/TextareaEnhance.tsx b/src/TextareaEnhance.tsx new file mode 100644 index 0000000..b17c7ae --- /dev/null +++ b/src/TextareaEnhance.tsx @@ -0,0 +1,58 @@ +import React, { useRef, useCallback } from 'react' +import { Textarea } from '@tarojs/components' +import { TextareaProps } from '@tarojs/components/types/Textarea' + +export interface TextareaEnhanceProps extends TextareaProps { + /** + * onBlur/onConfirm 事件也会触发 onChange. 如果 value 与最后一次 onChange 事件相同则跳过. + * + * @default true + */ + mergeChangeEvent?: boolean +} + +/** + * Textarea 升级版. + * + * - mergeChangeEvent onBlur/onConfirm 事件也会触发 onChange. + * + * 某些输入法(不只是中文), 输入中的文字并没有真正进入 Textarea 中, 只是浮动在上面的输入法自带 UI 控件. + * 另一些中文输入法会在词语联想过程中提前把拼音输入进输入框内. + * 这两种情况都会造成 onInput 事件不触发或传递错误的值. + * Textarea 组件的 onBlur/onConfirm 事件中汇报的值永远是正确的最终值. + */ +export const TextareaEnhance: React.FC = (props) => { + const { mergeChangeEvent = true, onInput, onBlur, onConfirm, ...rest } = props + + const previousInputValue = useRef() + + const handleInput = useCallback( + (e) => { + previousInputValue.current = e.detail.value + onInput(e) + }, + [onInput] + ) + + const handleBlur = useCallback( + (e) => { + if (mergeChangeEvent && e.detail.value !== previousInputValue.current) { + onInput({ ...e, detail: { ...e.detail, keyCode: 0 } }) + } + onBlur(e) + }, + [onBlur, mergeChangeEvent] + ) + + const handleConfirm = useCallback( + (e) => { + if (mergeChangeEvent && e.detail.value !== previousInputValue.current) { + onInput({ ...e, detail: { ...e.detail, keyCode: 0, cursor: 0 } }) + } + onConfirm(e) + }, + [onConfirm, mergeChangeEvent] + ) + + return