React Native - 多个自定义组件同时关注

React Native - Multiple custom components focuses at the same time

我是用 expo 响应原生的新手,我创建了一个功能组件,它试图做一些类似于 react-native-paper 的 TextInput 行为的事情,带有动画等等。

问题是我在同一个屏幕上有这个组件的多个实例,当我按下第一个写入它时,其余的也会获得焦点。如果我在第一个中填写任何文本,第二个会在未被触摸的情况下触发通知。

我正在使用 formik、Yup 和 typescript。

我是这样调用表单中的组件的:

    ...
    <ScrollView>
        <FloatingLabelInput
          label="Ciudad"
          marginBottom={20}
          onChangeText={text => {
            formik.setFieldValue('city', text)
          }}
          value={formik.values.city}
          error={formik.errors.city}
        />
        <FloatingLabelInput
          label="Calle principal"
          marginBottom={20}
          onChangeText={text => {
            formik.setFieldValue('mainStreet', text)
          }}
          value={formik.values.mainStreet}
          error={formik.errors.mainStreet}
        />
    </ScrollView>
    ....

组件定义:

    ...
export default function FloatingLabelInput(props: FloatingLabelInputProps) {
  const { label, style, onChangeText, value, error, containerStyle, border } = props
  
  useEffect(() => {
    if (value === '') {
      resetViewTransition.start()
      resetLabelTransition.start()
    }
  }, [value])

  const handleFocus = () => {
    animateViewTransition.start()
    animateLabelTransition.start()
  }

  const handleBlur = () => {
    if (value === '') {
      resetViewTransition.start()
      resetLabelTransition.start()
    }
  }

  const handleTextChange = (text: string) => {
    if (text.length > 0) {
      animateViewTransition.start()
      animateLabelTransition.start()
    }
    onChangeText && onChangeText(text)
  }

  return (
    <View style={styles(marginBottom).mainContainer}>
      <Animated.View style={[styles().container, error ? styles().containerError : border !== undefined && { borderColor: viewAnimationBorderColor(border) }, containerStyle]}>
        <Animated.Text style={[styles().labelStyle, { top: labelAnimationTop, fontSize: labelAnimationFontSize, color: labelAnimationColor }]}>{label}</Animated.Text>
        {secureTextEntry && <Icon name={passwordShown ? 'eye-outline' : 'eye-off-outline'} size={25} style={styles().eye} onPress={() => setPasswordShown(!passwordShown)} />}
        <TextInput
          selectionColor={error ? colors.fireEngineRed : border ? border : colors.nightRider}
          underlineColorAndroid="transparent"
          style={[styles().input, { color: error ? colors.fireEngineRed : border ? border : colors.nightRider }, style]}
          onChangeText={handleTextChange}
          value={value}
          onFocus={handleFocus}
          onBlur={handleBlur}
          keyboardType={defineKeyBoardType}
          maxLength={maxLength}
          secureTextEntry={secureTextEntry && !passwordShown}
          keyboardAppearance="dark"
        />
      </Animated.View>
      {error && (
        <HelperText type="error" style={styles().errorText}>
          {error}
        </HelperText>
      )}
    </View>
  )
}

您的“只要我更改一个字段,所有内容都会开始验证”是我以前遇到过的一个问题。对我来说似乎有用的是保留一个状态变量并仅在第一次调用 handleSubmit 后设置该状态变量。

Formik 验证依赖于状态变量,该变量最初为 false(所以它不是)

    <Formik
      enableReinitialize={true}
      validateOnMount={false}
      validateOnChange={this.state.validationEnabledOnChange}
      initialValues=...
      onSubmit={this.submitHandler}
    >

提交句柄更改以立即开始验证

  submitHandler = (values, actions) => {
    // Start validating all fields on change now..
    this.setState({
      validationEnabledOnChange: true
    })

    ... try to handle submit
   }

我不确定你的注意力问题。我看不到上面的代码会导致出现焦点。有一段时间,我确实使用了 react-native-formik 的 withNextInputAutoFocusForm 方法,它自动为我做了很多这样的事情。我想您可以研究他们的源代码,看看是否可以从中收集到一些东西。该项目开始老化并且没有跟上,所以他们的一些其他高阶组件导致我出现问题,我不得不摆脱对项目的很多依赖,所以我不建议您尝试开始使用它批发..

来源在这里:https://github.com/bamlab/react-native-formik

如果有人有相同的bug/error,我给他们我的解决方案:

首先,为了修复同时进行的动画,我拔了线:

const animationValue = new Animated.Value(0)

从我创建的 2 个动画文件(用于视图和 de 标签)并将它们放入通用组件中。通过这种方式,我将 animationValue 作为参数发送到其相应的动画文件。

  const animationValue = new Animated.Value(0)

  useEffect (() => {
    if (value === '') {
      resetViewTransition(animationValue).start()
      resetLabelTransition(animationValue).start()
      return
    }
    animateViewTransition(animationValue).start()
    animateLabelTransition(animationValue).start()
  }, [value])

  const handleFocus = () => {
    animateViewTransition(animationValue).start()
    animateLabelTransition(animationValue).start()
  }

  const handleBlur = () => {
    if (value === '') {
      resetViewTransition(animationValue).start()
      resetLabelTransition (animationValue).start()
    }
  }

  const handleTextChange = (text: string) => {
    if (text.length> 0) {
      animateViewTransition(animationValue).start ()
      animateLabelTransition(animationValue).start ()
    }
    onChangeText && onChangeText(text)
  }

我已经根据这个问题及其答案(示例)来修复动画:

https://snack.expo.io/@karthik.01/react.children

那么对于第二个问题,我必须使用我问题的另一个答案

通过这两项调整,我获得了表单中每个组件的独立性。