Tengo un proyecto en el que estoy dividiendo las palabras de diferentes campos de entrada y empujándolas a una matriz de content . La matriz debe 'recordar' todas las palabras que se han insertado en ella. Actualmente, cada vez que el usuario comienza a escribir un campo de entrada 'nuevo' (y vacío), la matriz de content se borra porque el valor está vacío.
Tengo una configuración de codesandbox aquí .
Entonces, digamos que el usuario escribe lorem ipsum dolar en el primer campo de entrada y sit amet en el segundo campo de entrada, la matriz de content debería ser así: ['lorem', 'ipsum', 'dolar', 'sit', 'amet']
¿Cómo puedo lograr este resultado?
Código de referencia
import "./styles.css"; import { useState } from "react"; export default function App() { const [fields, setFields] = useState([ { id: 1, value: "" }, { id: 2, value: "" } ]); const [content, setContent] = useState([]); const handleOnChange = (e, idx) => { let newField = [...fields]; newField[idx].value = e.target.value; setFields(newField); //How do I push both the values from field 1 AND 2 in the array? //Currently, when you switch from inputfield, the content array gets reset let words = e.target.value.split(" "); setContent(words); }; return ( <div> {fields.map((field, idx) => ( <div> <span>Field {idx}</span> <input className="border-2 border-red-500" type="text" key={field.id} value={field.value} onChange={(e) => handleOnChange(e, idx)} /> </div> ))} <div style={{ marginTop: "20px", backgroundColor: "gray" }}> {content.map((item, idx) => ( <div key={idx}>{item}</div> ))} </div> </div> ); }El content se deriva de las propiedades de value de estado de los fields y, en realidad, no es necesario almacenarlo en un estado. Calcule el content en cada renderizado.
const { useState } = React; function App() { const [fields, setFields] = useState([ { id: 1, value: "" }, { id: 2, value: "" } ]); const handleOnChange = (e, idx) => { setFields(prevFields => { const newFields = [...fields]; newFields[idx] = { ...newFields[idx], value: e.target.value }; return newFields; }); }; const content = fields.map(o => o.value).join(' ').split(' '); return ( <div> {fields.map((field, idx) => ( <div key={field.id}> <span>Field {idx}</span> <input className="border-2 border-red-500" type="text" value={field.value} onChange={(e) => handleOnChange(e, idx)} /> </div> ))} <div style={{ marginTop: "20px", backgroundColor: "gray" }}> {content.map((item, idx) => ( <div key={idx}>{item}</div> ))} </div> </div> ); } ReactDOM.render( <App />, root ); <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>Esta sintaxis permite agregar el elemento a la matriz existente actual:
setMyArray(oldArray => [...oldArray, newElement]);Hay que cambiar dos cosas:
onBlur para impulsar sus palabras en el content .ejemplo de trabajo: https://codesandbox.io/s/goofy-colden-8h5v5
import "./styles.css"; import { useState } from "react"; export default function App() { const [fields, setFields] = useState([ { id: 1, value: "" }, { id: 2, value: "" } ]); const [content, setContent] = useState([]); const handleOnChange = (e, idx) => { let newField = [...fields]; newField[idx].value = e.target.value; setFields(newField); }; const onBlur = (e, idx)=> { //How do I push both the values from field 1 AND 2 in the array? //Currently, when you switch from inputfield, the content array gets reset let words = fields[idx].value.split(" "); setContent([...content, ...words]); } return ( <div> {fields.map((field, idx) => ( <div> <span>Field {idx}</span> <input className="border-2 border-red-500" type="text" key={field.id} value={field.value} onChange={(e) => handleOnChange(e, idx)} onBlur={(e) => onBlur(e, idx)} /> </div> ))} <div style={{ marginTop: "20px", backgroundColor: "gray" }}> {content.map((item, idx) => ( <div key={idx}>{item}</div> ))} </div> </div> ); }