So i'm fairly new to react and im trying to make a pinpad screen now but im stuck. i dont know how to use useEfect for validation of a 4 digits pin in my app, as in, i am just confused where and how to write it so it actually works, is there any examples of it so i can see how to do it?
export default function App() {
const [pin, setPin] = useState("");
return (
<div>
<div>{pin}</div>
<div>
<div>
<button onClick={() => setPin((pin) => `${pin}1`)}>1</button>
<button onClick={() => setPin((pin) => `${pin}2`)}>2</button>
<button onClick={() => setPin((pin) => `${pin}3`)}>3</button>
</div>
<div>
<button onClick={() => setPin((pin) => `${pin}4`)}>4</button>
<button onClick={() => setPin((pin) => `${pin}5`)}>5</button>
<button onClick={() => setPin((pin) => `${pin}6`)}>6</button>
</div>
<div>
<button onClick={() => setPin((pin) => `${pin}7`)}>7</button>
<button onClick={() => setPin((pin) => `${pin}8`)}>8</button>
<button onClick={() => setPin((pin) => `${pin}9`)}>9</button>
</div>
<div>
<button onClick={() => setPin((pin) => pin.slice(0, pin.length - 1))}>
<
</button>
<button onClick={() => setPin((pin) => `${pin}0`)}>0</button>
<button onClick={() => setPin("")}>C</button>
</div>
</div>
</div>
);
}
CodePudding user response:
Just check for changes in your pin
state using the useEffect
dependency array, and then log the saved PIN if it reaches four digits.
In this example I've used an array to store the numbers which I then join
up. (I've also taken the liberty of using CSS Grid, and a Button component, so that code is as DRY as possible).
const { useEffect, useState } = React;
function Example({ test }) {
const [ pin, setPin ] = useState('');
const [ attempt, setAttempt ] = useState(0);
const [ lock, setLock ] = useState(false);
const [ message, setMessage ] = useState('');
// Reset the state if the "number" is "C"
// otherwise add the number to the state string
function handleClick(e) {
const { number } = e.target.dataset;
if (number === 'C') {
setPin([]);
} else {
setPin(`${pin}${number}`);
}
}
// If the pin state has changed,
// and the length of the array is four,
// log the state
useEffect(() => {
if (attempt < 3) {
if (pin.length === 4) {
if (pin !== test) {
setAttempt(attempt 1);
setPin('');
setMessage('Incorrect PIN.');
} else {
setMessage('PIN accepted');
}
}
} else {
setMessage('Failed to log in.');
setLock(true);
}
}, [pin]);
// Create a new array and map over the elements
// to create some buttons
return (
<div>
<div class="grid">
{new Array(9).fill('').map((el, i) => (
<Button lock={lock} number={i 1} handleClick={handleClick} />
))}
<Button lock={lock} number="0" handleClick={handleClick} />
<Button lock={lock} number="C" handleClick={handleClick} />
</div>
<div class="message">{message}</div>
</div>
);
}
function Button({ lock, number, handleClick }) {
return (
<button
disabled={lock}
data-number={number}
onClick={handleClick}
>{number}</button>
);
}
ReactDOM.render(
<Example test="1234" />,
document.getElementById('react')
);
.grid { width: 100px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.message { margin-top: 0.5em; }
<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="react"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can add a useEffect
hook with pin
as a dependency:
useEffect(() => {
console.log(pin, pin.length)
}, [pin])
the callback passed to useEffect
will be called every time pin
changes
CodePudding user response:
To validate any react state when state change you can use useEffect
like this.
useEffect(() => {
// pin state changed
}, [pin]);
useEffect
can be used when component mount, unmount or any state variable changes. Variables which are used inside square brackets (pin
in this example) are called dependent variables. That means when this variables changes it will run that specific code.
For more React useEffect hook