Mettre l'accent sur l'ENTRÉE après le rendu

Quelle est la façon de réagir en mettant l'accent sur un champ de texte particulier après que le composant est rendu?

La Documentation

semble suggérer l'utilisation des références, E. g:

définir ref="nameInput" sur mon champ d'entrée dans la fonction de rendu, puis appeler:

this.refs.nameInput.getInputDOMNode().focus(); 

mais Où dois-je l'appeler? J'ai essayé quelques endroits mais je n'arrive pas à le faire marcher.

376
demandé sur user5481342 2015-03-06 02:28:22
la source

19 ответов

vous devriez le faire dans componentDidMount et refs callback à la place. Quelque chose comme ça

componentDidMount(){
   this.nameInput.focus(); 
}

class App extends React.Component{
  componentDidMount(){
    this.nameInput.focus();
  }
  render() {
    return(
      <div>
        <input 
          defaultValue="Won't focus" 
        />
        <input 
          ref={(input) => { this.nameInput = input; }} 
          defaultValue="will focus"
        />
      </div>
    );
  }
}
    
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<div id="app"></div>
442
répondu Dhiraj 2017-03-28 20:19:34
la source

la réponse de @Dhiraj est correcte, et pour plus de commodité, vous pouvez utiliser le prop autoFocus pour avoir une mise au point automatique de l'entrée lorsqu'il est monté:

<input autoFocus name=...

notez que dans jsx c'est autoFocus (capital F) contrairement au vieux html ordinaire qui est insensible à la casse.

584
répondu FakeRainBrigand 2018-05-11 00:37:32
la source

à partir de React 0,15 , la méthode la plus concise est:

<input ref={input => input && input.focus()}/>
123
répondu Ilya Semenov 2016-10-27 12:19:30
la source

si vous voulez juste faire autofocus dans React, c'est simple.

<input autoFocus type="text" />

pendant que si vous voulez juste savoir où mettre ce code, la réponse est dans componentDidMount().

v014.3

componentDidMount() {
    this.refs.linkInput.focus()
}

dans la plupart des cas, vous pouvez attacher un ref au noeud DOM et éviter d'utiliser findDOMNode du tout.

lire les documents API ici: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode

49
répondu Jack Lee 2015-12-05 13:35:38
la source

je viens de tomber sur ce problème et j'utilise react 15.0.1 15.0.2 et j'utilise la syntaxe ES6 et je n'ai pas tout à fait obtenu ce dont j'avais besoin des autres réponses depuis v. 15 a chuté il y a des semaines et certaines des propriétés this.refs ont été dépréciées et supprimé .

en général, ce dont j'avais besoin était:

  1. concentrer le premier élément d'entrée (champ) lorsque le pièces de fixation
  2. focaliser le premier élément d'entrée (champ) avec une erreur (après soumettre)

j'utilise:

  • Réagir Conteneur/Présentation De La Composante
  • Redux
  • Réagir " Routeur

Focus le Premier Élément d'Entrée

j'ai utilisé autoFocus={true} le premier <input /> sur la page de sorte que lorsque le composant monte, ça va se concentrer.

focaliser le premier élément D'entrée avec une erreur

cela a pris plus de temps et a été plus alambiqué. Je garde hors code qui n'est pas pertinent à la solution pour la brièveté.

Redux Store /State

j'ai besoin d'un état global pour savoir si je dois définir la mise au point et la désactiver quand elle a été définie, donc je ne continue pas à re-définir la mise au point quand les composants sont re-rendus (je vais être utilisation de componentDidUpdate() pour vérifier la mise au point.)

cela pourrait être conçu comme vous le souhaitez pour votre application.

{
    form: {
        resetFocus: false,
    }
}

Composant Conteneur

le composant devra avoir l'ensemble de propriété resetfocus et un rappel pour vider la propriété si elle finit par mettre l'accent sur elle-même.

notez aussi, j'ai organisé mes créateurs D'Action dans des fichiers séparés principalement en raison de mon projet est assez grand et j'ai voulu casser en plusieurs morceaux gérables.

import { connect } from 'react-redux';
import MyField from '../presentation/MyField';
import ActionCreator from '../actions/action-creators';

function mapStateToProps(state) {
    return {
        resetFocus: state.form.resetFocus
    }
}

function mapDispatchToProps(dispatch) {
    return {
        clearResetFocus() {
            dispatch(ActionCreator.clearResetFocus());
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyField);

Présentation

import React, { PropTypes } form 'react';

export default class MyField extends React.Component {
    // don't forget to .bind(this)
    constructor(props) {
        super(props);
        this._handleRef = this._handleRef.bind(this);
    }

    // This is not called on the initial render so
    // this._input will be set before this get called
    componentDidUpdate() {
        if(!this.props.resetFocus) {
            return false;
        }

        if(this.shouldfocus()) {
            this._input.focus();
            this.props.clearResetFocus();
        }
    }

    // When the component mounts, it will save a 
    // reference to itself as _input, which we'll
    // be able to call in subsequent componentDidUpdate()
    // calls if we need to set focus.
    _handleRef(c) {
        this._input = c;
    }

    // Whatever logic you need to determine if this
    // component should get focus
    shouldFocus() {
        // ...
    }

    // pass the _handleRef callback so we can access 
    // a reference of this element in other component methods
    render() {
        return (
            <input ref={this._handleRef} type="text" />
        );
    }
}

Myfield.propTypes = {
    clearResetFocus: PropTypes.func,
    resetFocus: PropTypes.bool
}

vue d'ensemble

l'idée générale est que chaque champ de formulaire qui pourrait avoir une erreur et être concentré doit se vérifier et si elle a besoin de se concentrer sur elle-même.

il y a une logique opérationnelle qui doit se produire pour déterminer si le champ donné est le bon champ à cibler. Cela ne s'affiche pas car cela dépendra de l'application individuelle.

Lorsqu'un formulaire est soumis, cet événement doit placer le drapeau Global focus resetFocus à true. Ensuite, comme chaque composant se met à jour lui-même, il verra qu'il devrait vérifier pour voir s'il obtient le focus et si c'est le cas, envoyer l'événement pour réinitialiser le focus pour que les autres éléments n'aient pas à continuer à vérifier.

modifier Comme une note secondaire, j'ai eu ma logique d'entreprise dans un fichier " utilities "et je viens d'exporter la méthode et l'ai appelée dans chaque méthode shouldfocus() .

santé!

24
répondu jmbertucci 2016-05-13 17:46:42
la source

Les Docs React ont maintenant une section pour cela. https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute

 render: function() {
  return (
    <TextInput
      ref={function(input) {
        if (input != null) {
          input.focus();
        }
      }} />
    );
  },
22
répondu Kevin Suttle 2016-04-29 00:42:30
la source

Réf. Le commentaire de @Dave sur la réponse de @Dhiraj; une alternative est d'utiliser la fonctionnalité de rappel de l'attribut ref sur l'élément rendu (après qu'un composant le rende d'abord):

<input ref={ function(component){ React.findDOMNode(component).focus();} } />

plus d'informations

10
répondu o01 2015-05-26 14:49:10
la source

C'est la bonne façon, comment autofocus. Lorsque vous utilisez callback au lieu de string comme valeur ref, il est automatiquement appelé. Vous avez votre ref disponible que sans avoir besoin de toucher le DOM en utilisant getDOMNode

render: function() {
  return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
  this._input.focus();
},
10
répondu Pavel Hasala 2018-03-16 16:49:15
la source

Ce n'est plus la meilleure réponse. Comme de v0.13, this.refs peuvent ne pas être disponibles qu'APRÈS componentDidMount() fonctionne, dans quelques rares cas.

il suffit d'ajouter la balise autoFocus à votre champ d'entrée, comme FakeRainBrigand montré ci-dessus.

9
répondu GAEfan 2015-03-11 07:08:29
la source

vous pouvez placer cet appel de méthode à l'intérieur de la fonction de rendu. Ou à l'intérieur de la méthode du cycle de vie, componentDidUpdate

7
répondu Raza Gill 2015-03-06 03:14:34
la source

Notez qu'aucune de ces réponses a fonctionné pour moi avec un matériel-ui composant TextField . Par comment mettre l'accent sur un TextField matérialui? j'ai dû sauter à travers des cerceaux pour obtenir que cela fonctionne:

const focusUsernameInputField = input => {
  if (input) {
    setTimeout(() => {input.focus()}, 100);
  }
};

return (
  <TextField
    hintText="Username"
    floatingLabelText="Username"
    ref={focusUsernameInputField}
  />
);
6
répondu Lane Rettig 2017-06-16 14:08:00
la source

vous n'avez pas besoin de getInputDOMNode ?? dans ce cas...

il suffit simplement d'obtenir le ref et focus() il lorsque le composant est monté -- componentDidMount ...

import React from 'react';
import { render } from 'react-dom';

class myApp extends React.Component {

  componentDidMount() {
    this.nameInput.focus();
  }

  render() {
    return(
      <div>
        <input ref={input => { this.nameInput = input; }} />
      </div>
    );
  }

}

ReactDOM.render(<myApp />, document.getElementById('root'));
6
répondu Alireza 2018-04-05 02:35:56
la source

AutoFocus a fonctionné le mieux pour moi. J'avais besoin de changer un peu de texte pour une saisie de texte sur double-cliquez donc, c'est ce que j'ai:

<input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />

NOTE: pour régler le problème lorsque React place le signe d'insertion au début du texte, utilisez cette méthode:

setCaretToEnd(event) {
    var originalText = event.target.value;
    event.target.value = '';
    event.target.value = originalText;
}

trouvé ici: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js

3
répondu Luke Watts 2017-12-31 17:22:42
la source

Avertissement: ReactDOMComponent: Ne pas l'accès .getDOMNode () d'un noeud DOM; à la place, utilisez le noeud directement. Ce noeud DOM a été rendu par App .

devrait être

componentDidMount: function () {
  this.refs.nameInput.focus();
}
2
répondu Kirk Strobeck 2016-04-10 01:56:01
la source

la réponse la plus simple est d'ajouter le ref=" some name " dans l'élément text input et d'appeler la fonction ci-dessous.

componentDidMount(){
   this.refs.field_name.focus();
}
// here field_name is ref name.

<input type="text" ref="field_name" />
2
répondu Venkatesh Somu 2017-02-28 15:11:18
la source

j'ai le MÊME PROBLÈME MAIS j'ai aussi un peu d'animation, donc mon collègue suggère d'utiliser window.requestAnimationFrame

c'est l'attribut ref de mon élément:

ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}
2
répondu SHI1485 2017-09-06 13:20:33
la source

lire presque toute la réponse mais n'a pas vu un getRenderedComponent().props.input

Réglez votre entrée de texte refs

this.refs.username.getRenderedComponent().props.input.onChange('');

1
répondu nichery 2017-07-10 20:57:33
la source

Après avoir essayé beaucoup d'options ci-dessus sans succès, j'ai trouvé que C'était que j'étais disabling puis enabling l'entrée qui a causé le focus à être perdu.

j'ai eu un prop sendingAnswer qui aurait désactivé L'entrée pendant que je sondais le backend.

<Input
  autoFocus={question}
  placeholder={
    gettingQuestion ? 'Loading...' : 'Type your answer here...'
  }
  value={answer}
  onChange={event => dispatch(updateAnswer(event.target.value))}
  type="text"
  autocomplete="off"
  name="answer"
  // disabled={sendingAnswer} <-- Causing focus to be lost.
/>

une fois que j'ai retiré l'hélice désactivée, tout a recommencé à fonctionner.

1
répondu jackdh 2018-07-10 11:57:54
la source

version mise à jour vous pouvez vérifier ici

componentDidMount() {

    // Focus to the input as html5 autofocus
    this.inputRef.focus();

}
render() {
    return <input type="text" ref={(input) => { this.inputRef = input }} />
})
0
répondu Nijat Ahmadov 2016-12-28 01:20:36
la source

Autres questions sur