Ade N
Ade N

Reputation: 145

React - passing ref attribute as prop

I am trying to refactor the code by removing the Form into a different component.

import React, { Component } from "react";

const collections = [];

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: collections,
    };
  }

  handleSubmit = (e) => {
    e.preventDefault();
    const { data } = this.state,
      name = this.refs.name.value;
    this.setState({ data: [...data, { name }] }, () => {
      this.refs.name.value = "";
    });
  };

  render() {
    return (
      <div>
          ...
          </div>

          <hr />
          <Form onSubmit={this.handleSubmit} myRef={(ref) => (ref = "name")} />
      </div>
    );
  }
} 

Form component is taking a ref as an attribute.

const Form = ({ onSubmit, myRef }) => {
  return (
    <form onSubmit={onSubmit} className="mt-10 flex justify-between">
      <input
        className="bg-gray-300 rounded-lg px-4 py-3 outline-none"
        ref={myRef}
        type="text"
        placeholder="Category name"
      />
      <button type="submit" className="mt-5 hover:text-red-500 cursor-pointer">
        Add
      </button>
    </form>
  );
};

The ref attribute is passed into the App component using the example from a previous question React - passing refs as a prop

<Form onSubmit={this.handleSubmit} myRef={(ref) => (ref = "name")} />

However, I still get an error enter image description here

Upvotes: 0

Views: 1270

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281754

You need to store the ref in a class instance variable

<Form onSubmit={this.handleSubmit} myRef={(ref) => (this.name = ref)} />

and use it like

handleSubmit = (e) => {
    e.preventDefault();
    const { data } = this.state,
    const name = this.name.value;
    this.setState({ data: [...data, { name }] }, () => {
      this.name.value = "";
    });
  };

Working demo

Approach 2

you use React.createRef to create a ref like

constructor() {
   super();
   this.nameRef = React.createRef();
}

---
handleSubmit = (e) => {
    e.preventDefault();
    const { data } = this.state,
    const name = this.nameRef.current.value;
    this.setState({ data: [...data, { name }] }, () => {
      this.nameRef.current.value = "";
    });
  };
---

    <Form onSubmit={this.handleSubmit} myRef={this.nameRef} />

Upvotes: 1

Related Questions