Tengo un componente simple aquí donde configuro una variable de estado llamada input al valor de una matriz de números. Luego, dentro de useEffect llamo a una función que aleatoriza la matriz de estado inicial y coloca los resultados en una nueva variable de estado llamada output .
Necesito que mi matriz de entrada permanezca en el mismo orden. Sin embargo, está siendo mutado cuando llamo a la función shuffleArray .
Pensé que no había forma de alterar el valor de una variable pasada como parámetro, lo que sería posible si JavaScript admitiera el paso por referencia.
const App = () => { const [input, setInput] = React.useState([90, 32, 28, 8, 21, 24, 64, 92, 45, 98, 22, 21, 6, 3, 27, 18, 11, 56, 16, 42, 36, 2, 60, 38, 24, 8, 16, 76, 62, 14, 84, 32, 24, 18, 8, 5, 25, 68, 65, 26, 22, 2, 52, 84, 30, 8, 2, 90, 5, 34, 56, 16, 42, 36]); const [output, setOutput] = React.useState([]); const shuffleArray = (array) => { for (let i = array.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); let temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } React.useEffect(() => { setOutput(shuffleArray(input)); }, []) return ( <div> [ { input.length > 0 ? input.map((n, i) => ( <span key={i}> { (i? ", " : "") + n } </span> )) : "No array..." } ] </div> ); }; ReactDOM.render(<App />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="root"></div>La entrada se cambia porque esa es la forma en que funciona el paso por valor. Las primitivas no se pueden mutar sin reasignación. Sin embargo, cuando se trata de objetos (y matrices, como en este caso), las propiedades del objeto se pueden modificar sin reasignación.
Si desea mantener la entrada sin cambios, puede usar Array.from en su lugar y manipular una copia de la matriz.
const App = () => { const [input, setInput] = React.useState([90, 32, 28, 8, 21, 24, 64, 92, 45, 98, 22, 21, 6, 3, 27, 18, 11, 56, 16, 42, 36, 2, 60, 38, 24, 8, 16, 76, 62, 14, 84, 32, 24, 18, 8, 5, 25, 68, 65, 26, 22, 2, 52, 84, 30, 8, 2, 90, 5, 34, 56, 16, 42, 36]); const [output, setOutput] = React.useState([]); const shuffleArray = (array) => { const shuffled = Array.from(array); for (let i = shuffled.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); let temp = shuffled[i]; shuffled[i] = shuffled[j]; shuffled[j] = temp; } return shuffled; } React.useEffect(() => { setOutput(shuffleArray(input)); }, []) return ( <div> [ { input.length > 0 ? input.map((n, i) => ( <span key={i}> { (i? ", " : "") + n } </span> )) : "No array..." } ] </div> ); }; ReactDOM.render(<App />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="root"></div>Javascript en realidad pasa objetos y matrices por "Copia de una referencia" como se explica en esta respuesta SO: https://stackoverflow.com/a/13104500/17704187
Entonces, su función shuffleArray en realidad muta el contenido de la matriz de entrada.