The heading tag should say "Marco " to begin with and the button shows "polo". onClick they should interchange. I'm using useState and an array to do the job. They should keep interchanging. But after a round, they repeat. I guess on the third round. I cannot understand why this is happening.
import React, { useState } from "react"; import "../styles/App.css"; const App = () => { let arr = ["Marco", "Polo"]; const [input, setInput] = useState(arr[0]); const [inputButton, setInputBUtton] = useState(arr[1]); const changethis = () => { // console.log("Clicked"); // console.log(arr); let temp = arr[0]; arr[0] = arr[1]; arr[1] = temp; console.log(arr); setInput(arr[0]); setInputBUtton(arr[1]); }; return ( <div id="main"> <h1 id="marco-polo">{input}</h1> <button id="marco-polo-toggler" onClick={changethis}> {inputButton} </button> </div> ); }; export default App;
when I console log my array I'm getting like this.
(2) ['Polo', 'Marco']
(2) ['Polo', 'Marco']
(2) ['Marco', 'Polo']
(2) ['Polo', 'Marco']
(2) ['Polo', 'Marco']
(2) ['Marco', 'Polo']
(2) ['Polo', 'Marco']
The problem is that every time you change the state the component rerender and your arr is reset
you can either put your array outside your component so it is not redefined every render or you can use a state index instead
solution 1
import React, { useState } from "react";
import "../styles/App.css";
let arr = ["Marco", "Polo"];
const App = () => {
const [input, setInput] = useState(arr[0]);
const [inputButton, setInputBUtton] = useState(arr[1]);
const changethis = () => {
// console.log("Clicked");
// console.log(arr);
let temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
console.log(arr);
setInput(arr[0]);
setInputBUtton(arr[1]);
};
return (
<div id="main">
<h1 id="marco-polo">{input}</h1>
<button id="marco-polo-toggler" onClick={changethis}>
{inputButton}
</button>
</div>
);
};
export default App;
solution 2
import React, { useState } from "react";
import "../styles/App.css";
const App = () => {
let arr = ["Marco", "Polo"];
const [input, setInput] = useState(0);
const [inputButton, setInputBUtton] = useState(1);
const changethis = () => {
// console.log("Clicked");
// console.log(arr);
setInput(i => (i + 1) % arr.length);
setInputBUtton(i => (i + 1) % arr.length);
};
return (
<div id="main">
<h1 id="marco-polo">{arr[input]}</h1>
<button id="marco-polo-toggler" onClick={changethis}>
{arr[inputButton]}
</button>
</div>
);
};
export default App;
arr is redeclared each render cycle with the value ["Marco", "Polo"] and every third time they are swapped the enqueued state update is to the same value the state already is, so that rerender is skipped.
Move the arr array declaration outside the component so its reference is stable. Instead of mutating an arr variable that is redeclared each render cycle, you should just swap the state values.
Example:
const arr = ["Marco", "Polo"];
export default function App() {
const [input, setInput] = useState(arr[0]);
const [inputButton, setInputBUtton] = useState(arr[1]);
const changethis = () => {
setInput(inputButton);
setInputBUtton(input);
};
return (
<div id="main">
<h1 id="marco-polo">{input}</h1>
<button id="marco-polo-toggler" onClick={changethis}>
{inputButton}
</button>
</div>
);
}
If you still wanted to swap the arr array values you should still move the arr array out of the component so its value isn't reset each render. Use array destructuring assignment to swap the array values.
Example:
const arr = ["Marco", "Polo"];
export default function App() {
const [input, setInput] = useState(arr[0]);
const [inputButton, setInputBUtton] = useState(arr[1]);
const changethis = () => {
[arr[1], arr[0]] = [arr[0], arr[1]]; // swap element values
console.log(arr);
setInput(arr[0]);
setInputBUtton(arr[1]);
};
return (
<div id="main">
<h1 id="marco-polo">{input}</h1>
<button id="marco-polo-toggler" onClick={changethis}>
{inputButton}
</button>
</div>
);
}
you can manage your array in the state, and then you can perform an operation very easily. Maybe the below code will helpful for you.
import React, { useState } from 'react';
import './style.css';
export default function App() {
const [arr, setArray] = useState(['Marco', 'Polo']);
const [input, setInput] = useState(arr[0]);
const [inputButton, setInputBUtton] = useState(arr[1]);
const changethis = () => {
let temp = [];
temp.push(arr[1], arr[0]);
console.log(arr);
setArray(temp);
setInput(arr[0]);
setInputBUtton(arr[1]);
};
return (
<div id="main">
<h1 id="marco-polo">{input}</h1>
<button id="marco-polo-toggler" onClick={changethis}>
{inputButton}
</button>
</div>
);
}