Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native - useRef warning on function components

I have a simple function component that needs to use input refs in order to set correct focuses on submitting:

import React, { useRef } from 'react'
import { View, TextInput } from 'react-native'

export default function Login() {
  let usernameRef = useRef(null)
  let passwordRef = useRef(null)

  return (
    <View>
      <TextInput ref={usernameRef} />
      <TextInput ref={passwordRef} />
    </View>
  )
}

The problem is that using ref with new Hooks API still alerting a warn:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

I don't want to use classes. Tried using "forwardRef" and the warning still there:

import React, { createRef, forwardRef } from 'react'
import { View, TextInput } from 'react-native'

export default function Login() {
  let usernameRef = createRef()
  let passwordRef = createRef()
  const Input = forwardRef((props, ref) => (
    <TextInput ref={ref} {...props} />
  ))

  return (
    <View>
      <Input ref={usernameRef} />
      <Input ref={passwordRef} />
    </View>
  )
}

What I'm doing wrong?

like image 401
Alexandre Thebaldi Avatar asked May 31 '19 13:05

Alexandre Thebaldi


People also ask

Can I use useRef in functional component?

The useRef is a hook that allows to directly create a reference to the DOM element in the functional component. Syntax: const refContainer = useRef(initialValue); The useRef returns a mutable ref object.

Does useRef notify content changes?

useRef doesn't notify us when its content changes. Mutating the . current property doesn't cause a re-render. If we want to run some code when React attaches or detaches a ref to a DOM node, a callback ref is better suited.

How do you use REF in functional component React native?

To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.

Can we use ref on component?

We should not use ref attribute on function components because they do not have instances. React will assign the current property with Dom element when component mount and assign null to it when component unmount. ref updates happen before componentDidMount or componentDidUpdate methods.


2 Answers

It seems that unfortunately this is not yet supported on React Native (link to Github issue). That was on 2018, and it seems that by May 2019, it was still the same case.

If you are not running the latest version, you could try the latest version of React Native and see if it works, if anyone can confirm that.

like image 129
Yuan-Hao Chiang Avatar answered Oct 19 '22 04:10

Yuan-Hao Chiang


I think I solved this problem see the below code

App.js file:

import Input from './component/Input.js'
export default ({navigation}) => {
  const inputEmail = useRef(null);
  const inputPassword = useRef(null);
 const updateRef = ref => {
    inputPassword.current = ref.current;
  };
return (
<View style={[signInScrStyle.container]}>
<Input
              placeholder={'Email Address'}
              onSubmitEditing={() => {
                inputPassword.current.focus();
              }}
              updateRef={e => {
                updateRef(e);
              }}
              ref={inputEmail}
            />
<Input
              placeholder={'Password'}
             onSubmitEditing={() => {
                inputEmail.current.focus();
              }}
              updateRef={e => {
                updateRef(e);
              }}
              ref={inputPassword}
            />
</View>
);
}

input.js file:

export const Input = props => {
  const myRef = useRef(null);

  useEffect(() => {
    console.log(myRef);
    props.updateRef(myRef);

    return () => {};
  }, []);

  return (
  <View style={style.txtInputContainer}>
<TextInput
        style={style.txtInput}
        // onChangeText={text => onChangeText(text)}
        numberOfLines={1}
        autoCorrect={false}
        autoCapitalize={'none'}
        placeholder={props.placeholder}
        placeholderTextColor={'#fff'}
        onSubmitEditing={() => {
          props.onSubmitEditing();
        }}
        ref={myRef}

      />
</View>
);
}
like image 25
Mega Area Avatar answered Oct 19 '22 03:10

Mega Area