# Referencing

## Reference types

There are two kinds of referencing - *component* and *element* references.

Component reference returns you the `React.Component` instance (i.e. `<Form>` or `<CustomField>`). Element reference returns you an `HTMLElement` instance rendered by the component (i.e. `<form>`, `<input>` or `<select>`). Both are useful for different scenarios and can be accessed as described below.

## Form

### Component reference

```jsx
class MyForm extends React.Component {
  componentDidMount() {
    console.log(this.formRef) // Form component
    console.log(this.formRef.innerRef) // <form> element

    this.formRef.validate() // access internal methods
  }

  render() {
    return (
      <Form ref={form => this.formRef = form} />
    )
  }
}
```

### Inner reference

Reference the actual `<form>` element by providing the `innerRef` prop to the `Form` component:

```jsx
class MyForm extends React.Component {
  componentDidMount() {
    console.log(this.formElement) // <form> element
  }

  render() {
    return (
      <Form innerRef={element => this.formElement = element} />
    )
  }
}
```

> You can also access the inner reference by referencing the `Form` component and taking its `innerRef` property: `this.formRef.innerRef`. This is the same as providing `Form.props.innerRef` directly.

## Field

### Component reference

Reference the field component by providing the `ref` prop.

```jsx
class MyForm extends React.Component {
  componentDidMount() {
    console.log(this.fieldRef) // Field component
    console.log(this.fieldRef.innerRef) // field element (i.e. "input")
  }

  render() {
    return (
      <Form>
        <MyField
          ref={field => this.fieldRef = field}
          name="foo" />
      </Form>
    )
  }
}
```

### Inner reference

To reference the actual form element behind the field use `innerRef` prop.

```jsx
class MyForm extends React.Component {
  componentDidMount() {
    console.log(this.fieldElement); // field element (i.e. "input")
    this.fieldElement.focus();
  }

  render() {
    return (
      <Form>
        <MyField
          innerRef={field => this.fieldElement = field}
          name="foo" />
      </Form>
    )
  }
}
```

> **Beware** that `innerRef` will always reference the component where `Field.props.fieldProps` get destructed. You must always propagate the essential field props to the actual form element for both proper functioning and referencing.
>
> `innerRef` **will not** work if the form element is returned by another React Component (for example, when using `styled-components`). See the [Nested element node](/react-advanced-form/architecture/referencing.md#nested-element-node) reference example to handle those scenarios.

## Nested element node

When using third-party libraries which wrap the plain form components in their own components you need to map `innerRef` explicitly to return the reference to the `HTMLElement`.

Do so by accessing an `innerRef` prop inside your custom field component declaration:

```jsx
import { createField } from 'react-advanced-form'
import styled from 'styled-components'

/* Custom styled component */
const StyledInput = styled.input`
  ...
`

class Input extends React.Component {
  render() {
    const { innerRef, fieldProps } = this.props

    return (
      <StyledInput
        {...fieldProps}
        innerRef={innerRef} />
    )
  }
}

export default createField()(Input)
```

> Do not be confused, as `StyledInput.props.innerRef` is the prop expected by `styled-components,` while `Input.props.innerRef` is the prop (a function) passed to the custom field component from the `createField()` wrapper. Different third-party solutions may expose different interface to accept the inner reference function.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://redd.gitbook.io/react-advanced-form/architecture/referencing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
