Solución:
Tienes que cambiar la posición del cursor después el estado ha sido actualizado (setState()
no muta inmediatamente this.state
)
Para hacer eso, debes envolver this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1;
en una función y pasarlo como segundo argumento a setState
(llamar de vuelta).
handleKeyDown(event) {
if (event.keyCode === 9) { // tab was pressed
event.preventDefault();
var val = this.state.scriptString,
start = event.target.selectionStart,
end = event.target.selectionEnd;
this.setState(
{
"scriptString": val.substring(0, start) + 't' + val.substring(end)
},
() => {
this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1
});
}
}
jsfiddle
Para cualquiera que busque un ejemplo rápido de posición del cursor de React Hooks (16.8+):
import React { useRef } from 'react';
export default () => {
const textareaRef = useRef();
const cursorPosition = 0;
return <textarea
ref={textareaRef}
onBlur={() => textareaRef.current.setSelectionRange(cursorPosition, cursorPosition)}
/>
}
En este ejemplo, setSelectionRange
se utiliza para establecer la posición del cursor en el valor de cursorPosition
cuando la entrada ya no está enfocada.
Aquí hay una solución en una arquitectura de estilo hooks. Mi recomendación es cambiar el área de texto. value
y selectionStart
inmediatamente al insertar la pestaña.
import React, { useRef } from "react"
const CodeTextArea = ({ onChange, value, error }) => {
const textArea = useRef()
return (
<textarea
ref={textArea}
onKeyDown={e => {
if (e.key === "Tab") {
e.preventDefault()
const { selectionStart, selectionEnd } = e.target
const newValue =
value.substring(0, selectionStart) +
" " +
value.substring(selectionEnd)
onChange(newValue)
if (textArea.current) {
textArea.current.value = newValue
textArea.current.selectionStart = textArea.current.selectionEnd =
selectionStart + 2
}
}
}}
onChange={e => onChange(e.target.value)}
value={value}
/>
)
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)