Pooja
Pooja

Reputation: 55

How to focus element based on button click in React.js

I have two buttons and two text boxes. When I click on button one, it should automatically focus on textbox1. When I click on button two, it should automatically focus on textbox2.

The code:

import React, { Component } from "react";
import "./styles.css";

class App extends Component {
  handleClick(){
    alert("hi");
  }
  render() {
    return (
      <div className="App">
        <div>
          <button onClick={this.handleClick}>One</button>
          <button onClick={this.handleClick}>Two</button>
        </div>
        <div>
          <input type="text" name="one" id="one" placeholder="one" /> 
        </div>
        <div>
          <input type="text" name="two" id="two" placeholder="two" /> 
        </div>
      </div>
    );
  }
}
export default App;

Link to codesandbox

Upvotes: 0

Views: 20478

Answers (2)

0DDC0
0DDC0

Reputation: 5189

The focus call is something called a side effect. So you have to directly access the HTML dom element to call it.

Refs ( https://reactjs.org/docs/refs-and-the-dom.html ) Are the react way of accessing this native element. You basically setup a container variable and assign it to the react element interested. Behind the scenes react will link that variable to the native dom element on which you can call the primitive focus function.

There are two different ways to do this which is shown below.

import React, { useRef } from "react";
import "./styles.css";

function FormFunctionalComponent() {
  const input1 = useRef(null);
  const input2 = useRef(null);

  const handleClick1 = () => {
    input1.current.focus();
  }; 

  const handleClick2 = () => {
    input2.current.focus();
  };
  return (
    <div className="App">
      <h1>Functional Component</h1>
      <button onClick={handleClick1}>One</button>
      <button onClick={handleClick2}>Two</button>
      <div>
        <input ref={input1} type="text" name="one" id="one" placeholder="one" />
      </div>
      <div>
        <input ref={input2}  type="text" name="two" id="two" placeholder="two" />
      </div>
    </div>
  );
}

class FormClassComponent extends React.Component {
  constructor(props) {
    super(props);
    this.input1 = React.createRef();
    this.input2 = React.createRef();
  }
  handleClick1 = () => {
    this.input1.current.focus();
  }; 

  handleClick2 = () => {
    this.input2.current.focus();
  };

  render() {
    return (
      <div className="App">
        <h1>Class Component</h1>
        <button onClick={this.handleClick1}>One</button>
        <button onClick={this.handleClick2}>Two</button>
        <div>
          <input ref={this.input1} type="text" name="one" id="one" placeholder="one" />
        </div>
        <div>
          <input ref={this.input2} type="text" name="two" id="two" placeholder="two" />
        </div>
      </div>
    );
  }
}

export default function App() {
  return (
    <>
      <FormFunctionalComponent /> <hr />
      <FormClassComponent />
    </>
  );
}

This is the working codesandbox sample.

https://codesandbox.io/s/blissful-fog-xoj9t?file=/src/App.js

Upvotes: 6

1nj3ct0r
1nj3ct0r

Reputation: 53

You need to have an onClick event on the div and the call the focus() function on the input element that you can access by refs in react:

class App extends React.Component {
  
  render() {
    return (
      <div>
          <div onClick={() => {this.myInp.focus()}}>Focus Input</div>
          <input type="text" ref={(ip) => this.myInp = ip} />
      </div>
    )
  }
}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

In the above snippet ref={(ip) => this.myInp = ip} is a callback approach of declaring refs which is recommended by react-docs

Upvotes: 2

Related Questions