React, pass a reference created at the parent to the children

Viewed 54

I am refactoring my code and I have some logic in the parent that needs to evaluate the value of all the inputs its children have. For that, I am creating 4 references in the parent, and passing them as prop to its children. Like follows:

  // References (will be used in multiple functions)
  usernameInput = createRef(null);
  emailInput = createRef(null);
  passwordInput = createRef(null);
  repeatPasswordInput = createRef(null);

  ...

  render() {
     return (
        <View>
          <Form1 usernameInputRef={usernameInput} emailInputRef={emailInput} />
          <Form2 passwordInputRef={passwordInput} repeatPasswordInputRef={repeatPasswordInput} />
        </View>
     );
  }

And in each child, I am doing this:

  // This is Child1. For Child2 gonna be the same but with its props.
  const {
    usernameInputRef,
    emailInputRef,
  } = props;


  return (
     <>
       <TextInput
           ref={usernameInputRef}
           ...
        />
       <TextInput
           ref={emailInputRef}
        />
    </>
 );
  

The problem comes when I try to access the value of each child node in the parent... If I do this:

  const username = this.usernameInput.current.props.value; // <--- Works if the input is in the same component, and not in the child.
  
  console.log(username);

I get "null".

Any ideas? This was working before refactoring my code into multiple components...

UPDATE

TextInput code:

import React from "react";
import { View, StyleSheet } from "react-native";
import { TextInput as RNPTextInput, useTheme } from "react-native-paper";

const TextInput = forwardRef((props, ref) => {
  const { colors } = useTheme();

  let {
    placeholder,
    multiline,
    maxLength,
    secureTextEntry,
    color,
    icon,
    counter,
    onChange,
    onSubmit,
    onFocus,
    containerStyle,
  } = props;

  ...

  return (
    <>
      <View style={containerStyle || styles.inputContainer}>
        <RNPTextInput
          ref={ref}
          ...
1 Answers

There is an elegant solution for accessing data from a child. Just combine forwardRef with the useImperativeHandle hook.

Do this:

const TextInput = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    getText() {
      return text;
    },
  }));

And instead of acessing the text with this:

 const username = this.usernameInput.current.props.value

You will be able to get it with this:

const username = this.usernameInput.current.getText();

Here is a full example: https://medium.com/@nugen/react-hooks-calling-child-component-function-from-parent-component-4ea249d00740

Related