I'm using Redux Form (RF) in a React Native application. Everything works fine but I can not figure out how to get the refs
from the Field input to go to the next input field with Redux Form.
Without RF this solution would work just fine.
Here is my code:
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}/>
)
}
}
I'm passing on the property nextField
to the component to determine the next input field when the Next
key on the keyboard is clicked but I can not get the refs
property inside the RenderInput
component.
Any idea how to get the refs property?
This solution passes props from the Form
component to the RenderInput
component and passes a function call back.
Here's the code:
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}/>
)
}
}
So what happened here?
I assign the ref to local scope with
ref={(componentRef) => this.field1 = componentRef}
as @Ksyqo suggested. Thanks for the hint.I pass
refField="field1"
to the RenderInput and assign the value to the input ref propertyref = {refField}
. This will add the input object to the refs property.I assigned a
onEnter
function in the FieldI pass the function to the props of RenderInput and assign it to the
onSubmitEditing={onEnter}
function. Now we have bind the two functions together. That means ifonSubmitEditing
gets invoked theonEnter
function gets invoked as wellFinally, refer to the local field
field2
, get the rendered Component and use the refs, which we assigned in theInput
field, to set the focus. this.field2.getRenderedComponent().refs.field2.focus()
I don't know if this is the most elegant solution but it works.
For people who are using Redux Form + React Native Elements, just follow @Thomas Dittmar answer, and add the following prop to the 'FormInput' component: textInputRef={refField}
The newest version of React Native Element has added the focus() method, so you don't have to worry about that.
withRef
is deprecated, use forwardRef
instead.
I worked on getting a ref like this that worked for me.
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
/>
now access instance functions like this.
this.myRef.anyFunc()
I had a slightly different use case, but I imagine it works for the above as well.
I used the focus action
import { focus } from 'redux-form';
dispatch(focus('signIn', 'email'));
Then in the (custom) form field that contains the TextInput, I added in the render function
<TextInput
ref="email"
/>
formStates.filter((state) => meta[state]).map((state) => {
if(state === 'active'){
this.refs.email.focus()
}
})
No worries about the component nesting/hierarchy anymore.
来源:https://stackoverflow.com/questions/43917795/react-native-redux-form-use-keyboard-next-button-to-go-to-next-textinput-fie