TextareaAutosize 使用 Formik?

TextareaAutosize With Formik?

我正在使用 react-textarea-autosize and formik,我想知道如何正确地将 formik 的更改事件挂接到 TextareaAutosize?

   <Formik
          initialValues={{
            description: ''
          }}
          validationSchema={Yup.object().shape({

          })}
          onSubmit={(values, { setSubmitting, setErrors }) => {
            console.log('v', values)

          }}
          render={props => (
            <Form autoComplete="off">
              <div className="field">
                <label className="label">Description</label>
                <div className="control">
                  <TextareaAutosize
                    className="input"
                    onChange={props.handleChange}
                    onBlur={props.handleBlur}
                    name="description"
                    value={props.values.description}
                  />
                </div>
              </div>

            </Form>
          )}

所以当我执行 onSubmit 时,我确实看到了在文本区域中输入的数据,但是当我在文本区域中执行 "enter" 时,我得到了这些错误

onloadwff.js:71 Assertion failed: Input argument is not an HTMLInputElement
getFormProfile @ onloadwff.js:71
setFieldValue @ onloadwff.js:71
formKeydownListener @ onloadwff.js:71
onloadwff.js:71 Uncaught TypeError: Cannot read property 'type' of undefined
    at e.setFieldValue (onloadwff.js:71)
    at HTMLFormElement.formKeydownListener (onloadwff.js:71)
setFieldValue @ onloadwff.js:71
formKeydownListener @ onloadwff.js:71

有趣,我也有这个,它与 Formik 没有任何关系,onloadwff.jslastpass 有关,并且这个错误是从 chrome 扩展名:]

这是 Lastpass plugin/extension 的错误。

我找到了一些解决这个问题的方法。一种是通过 Lastpass plugin/extension 本身。

通过 Lastpass

对此添加例外 URL

  1. 单击扩展并转到“打开我的保险库”
  2. 导航到帐户设置
  3. 转到“从不 URL”选项卡
  4. 添加“http://localhost”(或您正在使用的 URL)并为类型选择“从不做任何事情”

通过代码

如果你想通过代码解决它(所以它不会发生在任何人身上,以防你将应用程序部署到生产环境),还有其他方法。

向表单元素添加 data-lpignore="true" 属性

示例:

<form data-lpignore="true"> 
  ... 
</form>

在你的例子中,表格应该是这样的:

            <Form autoComplete="off" data-lpignore="true">
              <div className="field">
                <label className="label">Description</label>
                <div className="control">
                  <TextareaAutosize
                    className="input"
                    onChange={props.handleChange}
                    onBlur={props.handleBlur}
                    name="description"
                    value={props.values.description}
                  />
                </div>
              </div>

            </Form>

停止事件传播

事件监听器

keydown 事件创建一个侦听器,并使用 event.stopPropagation():[=24 停止那里的 Enter 键(这似乎是 Lastpass 侦听的那个)的传播=]

document.addEventListener('keydown', handleHitEnter, true);
    
function handleHitEnter(event: globalThis.KeyboardEvent) {
  if (event && event.key === "Enter") {
    event.stopPropagation();
  }
}

我也看到有人用事件处理程序停止传播,但在我的例子中,没有任何效果,因为 LastPass 会在传播到任何处理程序之前先处理 keydown 事件。但我会在这里添加它作为另一个选项

事件处理程序

Angular 的事件处理程序:
<textarea matInput matTextareaAutosize
 formControlName="description"
 (keydown.enter)="enterEventHandler($event)"
></textarea>

像这样的 enterEventHandler:

enterEventHandler($event: KeyboardEvent): boolean {
  $event.stopPropagation()
  // handle form submission
}

React 的事件处理程序:

<textarea
  className="input"
  name="description"
  onKeyDown={event => enterEventHandler(event)}
/>
function enterEventHandler(event: KeyboardEvent<HTMLButtonElement>) {
  if (event && event.key === "Enter") {
    event.stopPropagation();
  }
}

参考文献:

  1. Error when hitting enter... Github discussion
  2. Stop LastPass filling out a form Whosebug discussion