Necesito obtener la pulsación de tecla de cada usuario cuando presionó una determinada tecla ("#") y dejar de obtener su pulsación de tecla cuando presionó otra tecla (espacio (" ")). Por ejemplo: un usuario ingresa el texto "Quiero ir a #comprar", necesito guardar su entrada y la etiqueta que contiene. ¿Cómo puedo hacerlo? Escribí un código para hacerlo, pero no sé cómo hacerlo completamente.
onKeyDown = (e) => { let value = e.target.value, tags = [], currentTag = ""; if (e.key == "Enter") { this.setState((state) => { const item = this.createNote(value, tags); return { notes: [...state.notes, item] }; }); } if (e.key == "#") {} };Puede hacer uso de expresiones regulares /#[^\s]+/g
Demo en vivo
export default function App() { const [value, setValue] = useState(""); const [tags, setTags] = useState([]); function onInputChange(e) { const value = e.target.value; setValue(value); const tags = value.match(/#[^\s]+/g) ?? []; setTags(tags); } return ( <> <input type="text" name="" value={value} onChange={onInputChange} /> <ul> {tags.map((tag) => { return <li key={tag}> {tag} </li>; })} </ul> </> ); } EDITED: You can make use of useMemo hook as
Gracias a 3limin4t0r
Demo en vivo
export default function App() { const [value, setValue] = useState(""); const tags = useMemo(() => value.match(/#\S+/g) || [], [value]); function onInputChange(e) { const value = e.target.value; setValue(value); } return ( <> <input type="text" name="" value={value} onChange={onInputChange} /> <ul> {tags.map((tag) => { return <li key={tag}> {tag} </li>; })} </ul> </> ); }En lugar de analizar valores clave individuales, puede usar una función como esta para analizar su campo de entrada en los cambios y devolver una serie de hashtags (sin el # inicial):
function parseTags (input: string): string[] { return (input.match(/(?:^#|[\s]#)[^\s]+/gu) ?? []).map(s => s.trim().slice(1)); }Aquí hay un ejemplo de trabajo en un componente funcional que incorpora la función:
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone@7.16.4/babel.min.js"></script> <div id="root"></div> <script type="text/babel" data-type="module" data-presets="react"> const {useState} = React; function parseTags (input) { return (input.match(/(?:^#|[\s]#)[^\s]+/gu) ?? []).map(s => s.trim().slice(1)); } function Example () { const [value, setValue] = useState(''); const [tags, setTags] = useState([]); const handleChange = (ev) => { const {value} = ev.target; setValue(value); setTags(parseTags(value)); }; return ( <div> <input type="text" onChange={handleChange} placeholder="Type here" value={value} /> <div>Parsed tags:</div> <ol> {tags.map((str, index) => <li key={`${index}.${str}`}>{str}</li>)} </ol> </div> ); } ReactDOM.render(<Example />, document.getElementById('root')); </script>Algo como esto debería funcionar para ti; Puedes adaptarte si no tienes acceso a los ganchos:
const RecorderInput = ({ onChange }) => { const [isRecording, setIsRecording] = useState(false); const toggleRecording = (e) => { const character = String.fromCharCode(e.charCode); if (character === '#') { setIsRecording(true); } if (character === ' ') { setIsRecording(false); } } const handleChange = (e) => { if (isRecording) onChange(e); toggleRecording(e); } <input type="text" onChange={handleChange} /> }Como otros sugirieron, su onChange también puede usar grupos de expresiones regulares para capturar hashes a medida que el usuario escribe. Pensando en esto ahora, probablemente sería mucho más limpio hacerlo de esta manera, pero la expresión regular está bien documentada, por lo que no me molestaré.