quitar poner foco ejemplos javascript reactjs

javascript - ejemplos - poner el foco en un input jquery



Establecer el foco en la entrada después del renderizado (23)

¿Cuál es la forma de reaccionar de establecer el foco en un campo de texto en particular después de que se representa el componente?

La documentación parece sugerir el uso de referencias, por ejemplo:

Establecer ref="nameInput" en mi campo de entrada en la función de renderizado, y luego llamar:

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

¿Pero a dónde debería llamar esto? He probado algunos lugares pero no puedo hacer que funcione.


Advertencia: ReactDOMComponent: No acceda a .getDOMNode () de un nodo DOM; en su lugar, use el nodo directamente. Este nodo DOM fue procesado por la App .

Debiera ser

componentDidMount: function () { this.refs.nameInput.focus(); }


Centrarse en el monte

Si solo desea enfocar un elemento cuando se monta (inicialmente se procesa), se hará un uso simple del atributo autoFocus.

<input autoFocus type="text" />

Enfoque dinámico

para controlar el enfoque dinámicamente, use una función general para ocultar los detalles de implementación de sus componentes.

Reaccionar 16.8 + componente funcional - useFocus hook

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

Luego úselo en cualquier componente funcional.

<input type="text" autoFocus />

Demo

Reaccionar 16.3 + Componentes de clase - utilizarFocus

const useFocus = () => { const htmlElRef = useRef(null) const setFocus = () => {htmlElRef.current && htmlElRef.current.focus()} return [ setFocus, htmlElRef ] }

Luego úsalo en cualquier componente de clase

const FocusDemo = () => { const [value, setValue] = useState("") const [setInputFocus, inputRef] = useFocus() const [setBtnFocus, btnRef] = useFocus() return ( <> {/* React.Fragment */} <input value={value} onChange={(e)=>{ setValue(e.target.value) if ( some logic ){ setBtnFocus() } }} ref={inputRef} /> <button onClick={setInputFocus} ref={btnRef} > Refocus </button> </> ) }

Demo


Árbitro. Comentario de @ Dave sobre la respuesta de @ Dhiraj; una alternativa es usar la funcionalidad de devolución de llamada del atributo ref en el elemento que se está representando (después de que un componente se procesa primero):

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

Más información


¿No necesitas getInputDOMNode ? en este caso...

Simplemente obtenga la ref y focus() cuando se monte el componente - 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''));


Acabo de encontrarme con este problema y estoy usando react 15.0.1 15.0.2 y estoy usando la sintaxis ES6 y no obtuve lo que necesitaba de las otras respuestas desde que la v.15 cayó hace semanas y algunas de this.refs propiedades this.refs quedaron en desuso y se removed .

En general, lo que necesitaba era:

  1. Enfoca el primer elemento de entrada (campo) cuando se monta el componente
  2. Enfoque el primer elemento de entrada (campo) con un error (después de enviar)

Estoy usando:

  • Contenedor de reacción / Componente de presentación
  • Redux
  • React-Router

Enfocar el primer elemento de entrada

autoFocus={true} en la primera <input /> en la página para que cuando el componente se monte, obtenga el foco.

Enfoque el primer elemento de entrada con un error

Esto tomó más tiempo y fue más complicado. Estoy manteniendo fuera el código que no es relevante para la solución por brevedad.

Tienda Redux / Estado

Necesito un estado global para saber si debo establecer el foco y deshabilitarlo cuando se configuró, por lo que no vuelvo a configurar el foco cuando los componentes se vuelven a procesar (usaré componentDidUpdate() para verificar ajuste de enfoque.)

Esto podría diseñarse como mejor le parezca para su aplicación.

{ form: { resetFocus: false, } }

Componente contenedor

El componente necesitará tener establecida la propiedad resetfocus y un callBack para borrar la propiedad si termina configurando el foco en sí mismo.

También tenga en cuenta que organicé mis Action Creators en archivos separados principalmente debido a que mi proyecto es bastante grande y quería dividirlos en trozos más manejables.

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);

Componente de presentación

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 }

Visión de conjunto

La idea general es que cada campo de formulario que podría tener un error y estar enfocado debe verificarse a sí mismo y si necesita establecer el enfoque en sí mismo.

Hay una lógica de negocios que debe suceder para determinar si el campo dado es el campo correcto para establecer el foco. Esto no se muestra porque dependerá de la aplicación individual.

Cuando se envía un formulario, ese evento debe establecer el indicador de foco global resetFocus en verdadero. Luego, a medida que cada componente se actualice, verá que debe verificar para ver si obtiene el foco y, si lo hace, enviar el evento para restablecer el foco para que otros elementos no tengan que seguir revisando.

editar Como nota al margen, tenía mi lógica de negocios en un archivo de "utilidades" y simplemente shouldfocus() el método y lo llamé dentro de cada método shouldfocus() .

¡Salud!


AutoFocus funcionó mejor para mí. Necesitaba cambiar algo de texto a una entrada con ese texto en doble clic, así que esto es lo que terminé con:

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

NOTA: Para solucionar el problema donde React coloca el cursor al comienzo del texto, use este método:

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

Encontrado aquí: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js


Dado que hay muchas razones para este error, pensé que también publicaría el problema que estaba enfrentando. Para mí, el problema era que representaba mis entradas como contenido de otro componente.

export default ({ Content }) => { return ( <div className="container-fluid main_container"> <div className="row"> <div className="col-sm-12 h-100"> <Content /> // I rendered my inputs here </div> </div> </div> ); }

Así es como llamé al componente anterior:

<Component Content={() => { return ( <input type="text"/> ); }} />


Debería hacerlo en componentDidMount y en su lugar la refs callback . Algo como esto

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>


Después de probar muchas opciones anteriores sin éxito, descubrí que fue como estaba disabling y luego enabling la entrada que causó que se perdiera el foco.

Tenía un accesorio que sendingAnswer una sendingAnswer que desactivaba la entrada mientras estaba sondeando el backend.

export default class DefaultRolesPage extends React.Component { addRole = ev => { ev.preventDefault(); const roleKey = this.roleKey++; this::updateState({ focus: {$set: roleKey}, formData: { roles: { $push: [{ id: null, name: '''', permissions: new Set(), key: roleKey, }] } } }) } render() { const {formData} = this.state; return ( <GridForm onSubmit={this.submit}> {formData.roles.map((role, idx) => ( <GridSection key={role.key}> <GridRow> <GridCol> <label>Role</label> <TextBox value={role.name} onChange={this.roleName(idx)} autoFocus={role.key === this.state.focus}/> </GridCol> </GridRow> </GridSection> ))} </GridForm> ) } }

Una vez que eliminé el accesorio deshabilitado, todo comenzó a funcionar nuevamente.


Esta es la forma correcta, cómo enfocar automáticamente. Cuando usa la devolución de llamada en lugar de la cadena como valor de referencia, se llama automáticamente. Tienes tu referencia disponible que sin la necesidad de tocar el DOM usando getDOMNode

render: function() { return <TextInput ref={(c) => this._input = c} />; }, componentDidMount: function() { this._input.focus(); },


Esta ya no es la mejor respuesta. A partir de v0.13, this.refs puede no estar disponible hasta AFTER componentDidMount() , en algunos casos extraños.

Simplemente agregue la etiqueta de autoFocus a su campo de entrada, como FakeRainBrigand mostró arriba.


La respuesta de @ Dhiraj es correcta, y para su comodidad, puede usar el accesorio de enfoque automático para que una entrada se enfoque automáticamente cuando se monta:

<input autoFocus name=...

Tenga en cuenta que en jsx es autoFocus (mayúscula F) a diferencia del viejo html que no distingue entre mayúsculas y minúsculas.


La respuesta más simple es agregar ref = "algún nombre" en el elemento de texto de entrada y llamar a la siguiente función.

componentDidMount(){ this.refs.field_name.focus(); } // here field_name is ref name. <input type="text" ref="field_name" />



Para mover el foco a un elemento recién creado, puede almacenar la ID del elemento en el estado y usarlo para configurar el autoFocus . p.ej

<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. />

De esta manera, ninguno de los cuadros de texto se enfoca en la carga de la página (como quiero), pero cuando presiona el botón "Agregar" para crear un nuevo registro, ese nuevo registro se enfoca.

Dado que autoFocus no se "ejecuta" nuevamente a menos que el componente se vuelva a montar, no tengo que molestarme en desarmar this.state.focus (es decir, no seguirá robando el foco mientras actualizo otros estados).


Puede poner esa llamada al método dentro de la función de renderizado. O dentro del método del ciclo de vida, componentDidUpdate


React 16.3 agregó una nueva forma conveniente de manejar esto mediante la creación de una referencia en el constructor del componente y usarlo como a continuación:

render: function() { return ( <TextInput ref={function(input) { if (input != null) { input.focus(); } }} /> ); },

Para más detalles, puede consultar este artículo en el blog React.

Actualizar:

A partir de React 16.8 , useRef hook se puede usar en componentes de función para lograr el mismo resultado:

class MyForm extends Component { constructor(props) { super(props); this.textInput = React.createRef(); } componentDidMount() { this.textInput.current.focus(); // one important change here is that we need to access the element via current. } render() { // instead of using arrow function, the created ref can be used directly. return( <div> <input ref={this.textInput} /> </div> ); } }


Si solo desea realizar el enfoque automático en React, es simple.

const utilizeFocus = () => { const ref = React.createRef() const setFocus = () => {ref.current && ref.current.focus()} return {setFocus, ref} }

Mientras que si solo quiere saber dónde colocar ese código, la respuesta está en componentDidMount ().

v014.3

class App extends Component { constructor(props){ super(props) this.input1Focus = utilizeFocus() this.BtnFocus = utilizeFocus() } render(){ return ( <> {/* React.Fragment */} <input value={value} onChange={(e)=>{ setValue(e.target.value) if ( some logic ){ this.BtnFocus.setFocus() } }} ref={this.input1Focus.ref} /> <button onClick={this.input1Focus.setFocus()} ref={this.BtnFocus.ref} > Refocus </button> </> ) } }

En la mayoría de los casos, puede adjuntar una referencia al nodo DOM y evitar el uso de findDOMNode.

Lea los documentos de la API aquí: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode



Tengo el mismo problema pero también tengo algo de animación, por lo que mi colega sugiere usar window.requestAnimationFrame

Este es el atributo ref de mi elemento:

ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}


Versión actualizada puedes consultar aquí

componentDidMount() { // Focus to the input as html5 autofocus this.inputRef.focus(); } render() { return <input type="text" ref={(input) => { this.inputRef = input }} /> })


getRenderedComponent().props.input casi toda la respuesta pero no vi un getRenderedComponent().props.input

Configure sus referencias de entrada de texto

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


A partir de React 0.15 , el método más conciso es:

<input ref={input => input && input.focus()}/>