Hola, gracias por la ayuda, con el siguiente código en reaccionar, quiero replicar el botón de clic cada vez que hago clic en él. Actualmente no pasa nada, pero si la consola muestra que la matriz crece. Aquí la caja de arena:
https://codesandbox.io/s/charming-glitter-0ntxmj?file=/src/App.js
const { useEffect, useState } = React; function App() { const btn = [ <button onClick={() => { btn.push(btn[0]); console.log(btn); }} > Click </button> ]; /* useEffect(()=>{ btn },[btn])*/ return ( <div className="App"> <div> {btn.map((e) => { return e; })} </div> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
Actualizar una variable local en un componente de función no funciona de esa manera. Se comporta como una función normal, btn
solo existe durante la ejecución de App()
.
Para conservar los valores en los renderizados, debe usar state . Sin embargo, las actualizaciones del estado y los accesorios son las únicas cosas que provocan repeticiones en primer lugar, por lo que es probable que la App
solo se reproduzca una vez al principio.
Si convierte esto directamente al estado de uso, se encontrará con el antipatrón de almacenar componentes en el estado. Para evitar eso, debemos modificar la lógica para almacenar solo algunos elementos genéricos en la matriz de estado para que nuestra lógica de representación pueda determinar cuántos botones mostrar.
Considere la siguiente opción:
const { useState } = React; function App() { const [btns, setBtns] = useState(['value']) function handleAdd() { setBtns((prev) => ([...btns, 'value'])); } return ( <div className="App"> <div> {btns.map((e) => ( <button onClick={handleAdd} > Click </button> ))} </div> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
Puede simplificar aún más almacenando solo el recuento de botones en su estado:
const { useState } = React; function App() { const [btnCount, setBtnCount] = useState(1) function handleAdd() { setBtnCount(btnCount + 1); } return ( <div className="App"> <div> {Array.from({ length: btnCount}).map((e) => ( <button onClick={handleAdd} > Click </button> ))} </div> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
Sí, se realizan cambios en su componente y sí, puede verlos en la consola, pero
Entonces, para resolver este problema, puede usar el estado, aunque la aplicación sigue siendo una función, useState garantizará que si el valor de la matriz cambia, React recordará los cambios por usted, y React también volverá a renderizar su componente cuando el estado cambios.
Tenga en cuenta también que puede cambiar el valor del estado solo usando la función proporcionada setBtns
y mutar los btns
no actualizará su componente, y la mutación del estado siempre es una fuente de errores.
const [btns, setBtns] = useState([ <button onClick={() => setBtns((prev) => [...prev, prev[0]])} > Click </button> ]);