web-dev-qa-db-fra.com

Détecter si l'élément d'entrée est concentré dans ReactJS

Comment détecter si un élément d'entrée tel que celui-ci est actuellement focalisé dans une fonction de rendu ReactJS?

<input type="text" style={searchBoxStyle} placeholder="Search"></input>   

Vous pouvez exécuter quelque chose comme ceci à tout moment tant que le nœud d'entrée est monté et qu'il y a une référence:

const ReactDOM = require('react-dom')

if ( document.activeElement === ReactDOM.findDOMNode(this.refs.searchInput) )

Vous devrez ajouter une référence à l'élément input:

<input ref="searchInput" ...

Cependant, vous ne devriez pas faire cela dans la méthode render, car le nœud d'entrée pourrait ne pas être encore monté. Utilisez une méthode de cycle de vie telle que componentDidUpdate ou componentDidMount.

Une autre solution consiste à ajouter des écouteurs d'événements pour les événements focus et blur à l'intérieur du champ de saisie:

<input type="text" onFocus={this.onFocus} onBlur={this.onBlur}...

Puis définissez les états dans les gestionnaires et vérifiez cet état dans la méthode de rendu.

onBlur: function() {
    this.setState({ focused: false })
},
onFocus: function() {
    this.setState({ focused: true })
},
render: function() {
    if ( this.state.focused ) {
        // do something
    }
    <input onFocus={this.onFocus} onBlur={this.onBlur}...
}

Notez que cela appellera un rendu à chaque fois que le nœud est concentré ou flou (mais c'est ce que vous voulez, n'est-ce pas?)

53
David Hellsing

J'ai commencé par la réponse donnée par David, dans laquelle il décrit deux méthodes qui fonctionnaient toutes les deux pour moi, mais je craignais les deux:

  1. Dans le premier cas, il utilise findDOMNode, ce qui présente certains inconvénients: au minimum, son utilisation est déconseillée et elle peut facilement être mise en œuvre de manière à être considérée comme un anti-modèle; De plus, cela peut ralentir le code en contournant le DOM virtuel et en travaillant directement avec le DOM.

  2. Dans la deuxième option, créer et gérer un état de composant uniquement pour trouver que la réponse semble trop demander, peut facilement se désynchroniser et peut rendre le composant inutilement rendu de nouveau.

Alors, essayant d’explorer davantage le problème, j’ai trouvé la solution suivante:

if (this.props.id === document.activeElement.id) {
  // your code goes here
}

Le même commentaire sur la réponse de David s'applique:

Cependant, vous ne devriez pas faire cela dans la méthode de rendu, car le nœud d'entrée pourrait ne pas être encore monté. Utilisez une méthode de cycle de vie telle que composantDidUpdate ou composantDidMount.

Avantages:

  • utilise les propriétés actuelles du composant (quelles sont les valeurs immuables)
  • ne nécessite pas de gestion d'état, et donc ne causera pas de re-rendu inutile
  • ne nécessite pas de DOM transversal, les performances doivent donc être aussi bonnes que possible
  • il n'est pas nécessaire de créer une référence de composant

Exigences:

  • votre composant devrait avoir et la propriété id qui est transmise à l'élément de formulaire à vérifier (quel que soit le cas le plus probable)
14
Marcos Abreu