【问题标题】:React Native + Redux Form - Use keyboard next button to go to next TextInput fieldReact Native + Redux Form - 使用键盘下一个按钮转到下一个 TextInput 字段
【发布时间】:2017-05-11 14:07:46
【问题描述】:

我在 React Native 应用程序中使用 Redux Form (RF)。一切正常,但我不知道如何从 Field 输入中获取 refs 以使用 Redux Form 转到下一个输入字段。

没有 RF this 解决方案可以正常工作。

这是我的代码:

class RenderInput extends Component {
   const { input, nextField, refs,
        meta: { touched, error, warning },
        input: { onChange } } = this.props
   render() {
      return (
         <Input
            returnKeyType = {'next'}
            onChangeText={onChange}
            onBlur={input.onBlur}
            onFocus={input.onFocus}
            onSubmitEditing = {(event) => {
               // refs is undefined
               refs[nextField].focus()
            }}/>
      )
   }
}

class Form extends Component {
   render() {
      return (
         <Field
            name="field1"
            focus
            withRef
            ref='field1'
            nextField = "field2"
            component={RenderInput}/>

         <Field
            name="vendor"
            withRef
            ref="field2"
            nextAction = "field3"
            component={RenderInput}/>
      )
   }
}

当单击键盘上的Next 键时,我将属性nextField 传递给组件以确定下一个输入字段,但我无法在RenderInput 组件中获取refs 属性。

知道如何获取 refs 属性吗?

【问题讨论】:

  • 只是说,直接分配 ref 已被弃用。最好的办法是将 ref 分配给一个可以重用的全局变量:ref={(componentRef) =&gt; this.myRef = componentRef}。见React Documentation
  • 我在这里发帖 stackoverflow.com/a/56401396/6242582 我是如何解决这个问题的。

标签: react-native redux-form


【解决方案1】:

此解决方案将 props 从 Form 组件传递到 RenderInput 组件并传回函数回调。

代码如下:

class RenderInput extends Component {
   const { input, refField, onEnter,
        meta: { touched, error, warning },
        input: { onChange } } = this.props
   render() {
      return (
         <TextInput
            ref = {refField}
            returnKeyType = {'next'}
            onChangeText={onChange}
            onBlur={input.onBlur}
            onFocus={input.onFocus}
            onSubmitEditing={onEnter}/>
      )
   }
}

class Form extends Component {
   render() {
      return (
         <Field
            name="field1"
            focus
            withRef
            ref={(componentRef) => this.field1 = componentRef}
            refField="field1"
            component={RenderInput}
            onEnter={() => { 
               this.field2.getRenderedComponent().refs.field2.focus()
            }}/>

         <Field
            name="field2"
            withRef
            ref={(componentRef) => this.field2 = componentRef}
            refField="field2"
            component={RenderInput}/>
      )
   }
} 

那么这里发生了什么?

  1. 按照@Ksyqo 的建议,我使用ref={(componentRef) =&gt; this.field1 = componentRef} 将引用分配给本地范围。感谢您的提示。

  2. 我将refField="field1" 传递给RenderInput 并将值分配给输入引用属性ref = {refField}。这会将输入对象添加到 refs 属性。

  3. 我在字段中分配了onEnter 函数

  4. 我将函数传递给 RenderInput 的 props 并将其分配给 onSubmitEditing={onEnter} 函数。现在我们已经将这两个函数绑定在一起了。这意味着如果onSubmitEditing 被调用,onEnter 函数也会被调用

  5. 最后,参考本地字段field2,获取渲染的组件,并使用我们在Input字段中分配的refs来设置焦点。 this.field2.getRenderedComponent().refs.field2.focus()

我不知道这是否是最优雅的解决方案,但它确实有效。

【讨论】:

  • 我仍然遇到的一个问题是,如果我从另一个文件导入 RenderInput 类,那么我会得到错误焦点不是函数。但如果我用相同的文件定义它就可以了。
  • 确保您的exportimport RenderInput 组件正确。我发布的解决方案应该是两个单独的文件。它肯定对我有用。
  • 另外,使用 class RenderInput extends Component{} 这样的 React 组件非常重要,因为 getRenderedComponent() 不适用于无状态函数组件。
  • 很奇怪。 RenderInput 确实渲染到屏幕上。它只是失败的 foucs() 函数。
  • 过去可能有效,但现在无效。 field2.getRenderedComponent().refs 现在是空对象
【解决方案2】:

对于使用 Redux Form + React Native Elements 的人,只需按照 @Thomas Dittmar 的回答,并将以下道具添加到“FormInput”组件:textInputRef={refField}

最新版本的 React Native Element 新增了 focus() 方法,所以你不必担心。

【讨论】:

  • 我面临一个问题,这样做会破坏字段的验证(它总是验证为真)。你以前遇到过吗?
【解决方案3】:

withRef 已弃用,请改用forwardRef

【讨论】:

    【解决方案4】:

    我努力获得这样一个对我有用的参考。

               const renderComp = ({
                 refName,
                 meta: { touched, error },
                 input,
                 ...custom
               }) => (
                 <MyComponent
                   ref={refName}
                   {...custom}
                 />
               )
    
                <Field
                  name={name}
                  component={renderComp}
                  ref={node =>
                    isLeft ? (this.compRef1 = node) : (this.compRef2 = node)}
                  refName={node =>
                     (this.myRef= node) }
                  withRef
                />
    

    现在像这样访问实例函数。

    this.myRef.anyFunc()
    

    【讨论】:

      【解决方案5】:

      我有一个稍微不同的用例,但我想它也适用于上述情况。

      我使用了焦点动作

      import { focus } from 'redux-form';
      dispatch(focus('signIn', 'email'));
      

      然后在包含TextInput的(自定义)表单字段中,我在渲染函数中添加了

      <TextInput
          ref="email"
      />
      formStates.filter((state) => meta[state]).map((state) => {
         if(state === 'active'){
            this.refs.email.focus()
         }
      })
      

      不再担心组件嵌套/层次结构。

      【讨论】:

        猜你喜欢
        • 2015-12-21
        • 2019-09-09
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多