I'm trying out the new react for functions without class and i'm trying to use setstate but it's not working, saying undefined if i used it straight or saying it's not a function if i remove this.
from it.
here is my code
import './App.css';
import React, { useState } from 'react';
function App() {
var [sum1, setSum1] = useState(0);
var [sum2, setSum2] = useState(0);
function handleClick(props) {
let buttonText = props.target.value;
let inputText = document.getElementById('result').value;
console.log(inputText buttonText);
// let sum1 =setState;
// let sum2 =setState;
let total = inputText buttonText;
if (total.charAt(0) === "0") {
} else {
document.getElementById("result").value = total;
}
if (props.target.value === "clear") {
document.getElementById("result").value = "";
}
if (props.target.value === " ") {
sum1 =document.getElementById("result").value.slice(0, -1);
setSum1({sum1:parseFloat(sum1)});
// alert(sum1);
document.getElementById("result").value = "";
alert(sum1);
}
if (props.target.value === "=") {
sum2 =document.getElementById("result").value.slice(0, -1);
setSum2({sum2:parseFloat(sum2)});
alert(sum1 sum2);
document.getElementById("result").innerText = sum1 sum2;
}
return total;
}
// function handleClick2(props) {
// document.getElementById("ans").innerHTML = eval(document.getElementById("result").value);
// }
return (
<div className="App">
<div id="ans" className="answer">Ans = 0</div>
<input type="text" onChange={handleClick} readOnly placeholder="0" className="inputid" id="result"/>
<hr/>
{/* calculator buttons below */}
{/* button */}
<button className="opbut" value=" " onClick={handleClick}> </button>
{/* button - */}
<button className="opbut" value="-" onClick={handleClick}>-</button>
{/* button × */}
<button className="opbut" value="*" onClick={handleClick}>×</button>
{/* button ÷ */}
<button className="opbut" value="/" onClick={handleClick}>÷</button>
{/* button 0 */}
<button className="calbut" value={0} onClick={handleClick}>0</button>
{/* button 1 */}
<button className="calbut" value={1} onClick={handleClick}>1</button>
{/* button 2 */}
<button className="calbut" value={2} onClick={handleClick}>2</button>
{/* button 3 */}
<button className="calbut" value={3} onClick={handleClick}>3</button>
{/* button 4 */}
<button className="calbut" value={4} onClick={handleClick}>4</button>
{/* button 5 */}
<button className="calbut" value={5} onClick={handleClick}>5</button>
{/* button 6 */}
<button className="calbut" value={6} onClick={handleClick}>6</button>
{/* button 7 */}
<button className="calbut" value={7} onClick={handleClick}>7</button>
{/* button 8 */}
<button className="calbut" value={8} onClick={handleClick}>8</button>
{/* button 9 */}
<button className="calbut" value={9} onClick={handleClick}>9</button>
{/* button ( */}
<button className="opbut" value="clear" onClick={handleClick}>C</button>
{/* button ) */}
<button className="opbut" value="Del" onClick={handleClick}>Del</button>
{/* button % */}
<button className="opbut" value="%" onClick={handleClick}>%</button>
{/* button y^ */}
<button className="opbut" value="^" onClick={handleClick}>y^</button>
{/* button total = */}
<button className="ansbut" value="=" onClick={handleClick}>=</button>
<hr/>
<div className="appName">A Simple React Calculator - Jayflo</div>
</div>
);
}
export default App;
above is the code.... as i'm trying to select a button, and onclick operator selected, setstate and delete textfield then accept another input and operate both input...
CodePudding user response:
React has its own particular way of updating the DOM based on the state of (value of) the elements, so you can't use native element methods.
In this example we use three hooks: useState
, useEffect
, and useRef
.
useState
maintains the state of the input element, the updated calculation, and the final evaluation which is passed into the result div.
useEffect
ensures that after the result has been completed we clear the calc
state.
useRef
is React's way of identifying an element. In this case, after each button is clicked, the input element is focused on again.
Here's a working example based on your code.
const { useRef, useEffect, useState } = React;
function Example() {
const [ input, setInput ] = useState('');
const [ calc, setCalc ] = useState('');
const [ result, setResult ] = useState('');
const inputRef = useRef();
// Update the input state when the value is changed
function handleInput(e) {
const { value } = e.target;
setInput(value);
}
// When the input is no longer focused (we've clicked
// a button) update the `calc` state
function handleBlur(e) {
const { value } = e.target;
setCalc(prev => prev value);
}
// When we click a button, either update the `calc` state,
// or if we click "=", update the `result` state
function handleClick(e) {
const { nodeName, value } = e.target;
if (nodeName === 'BUTTON') {
setInput('');
inputRef.current.focus();
switch(value) {
case '=': {
setResult(eval(calc));
break;
}
case 'clear': {
setCalc('');
break;
}
default: {
setCalc(prev => prev value);
break;
}
}
}
}
// When the result is updated, clear the `calc` state
useEffect(() => setCalc(''), [result]);
return (
<div class="container">
<div>
<div>{`Result: ${result}`}</div>
<div>{`Calc: ${calc}`}</div>
<input autoFocus ref={inputRef} onBlur={handleBlur} onChange={handleInput} type="text" value={input} />
</div>
<div class="buttons" onClick={handleClick}>
<button value=" "> </button>
<button value="-">-</button>
<button value="*">×</button>
<button value="/">÷</button>
<button value="0">0</button>
<button value="1">1</button>
<button value="2" >2</button>
<button value="3">3</button>
<button value="4">4</button>
<button value="5">5</button>
<button value="6">6</button>
<button value="7">7</button>
<button value="8">8</button>
<button value="9">9</button>
<button value="clear">C</button>
<button value="Del">Del</button>
<button value="%">%</button>
<button value="^">y^</button>
<button value="=">=</button>
</div>
</div>
);
};
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
.container { display: flex; width: 200px; height: 200px; }
.buttons {
padding: 10px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 2px;
}
button {
background: rgba(0, 0, 0, 0.5);
border: 1px solid #111;
padding: 10px;
color: #EEE;
border-radius: 5px;
font-size: 12px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
CodePudding user response:
Let's say you want to keep track of a pending state
To make use of useState, first you have to import it
import { useState } from "react";
Then,
const [ isPending , setIsPending ] = useState(false);
the value you pass to the useState(initialValue)
function will be the initial value of the state.
You can pass any value like array
string
or object
to the useState()
function
To set/change the value of the state you declared
setIsPending(true);
The value of your state is held by the isPending
variable
CodePudding user response:
UPDATED: About your Calculator
What you're showing is mixing react and HTML and Vanilla JS. It's not well seen and it's harder to maintain. So, the react approach is available in this new code sandbox:
(It's only handling the Sum, as an example purpose of how we can do this application using only react)
https://codesandbox.io/s/falling-star-hf90r
About USE STATE
You can see one example working here: https://codesandbox.io/s/intelligent-cori-5xi34?file=/src/App.js:50-759
The easiest way to do this is using hooks. Now, there are multiple hooks. In your case, you will need React.useState
, it'll return 2 things: the value, the setter.
const [myValue, mySetter] = React.useState(defaultValue);
After that, everything will work almost the same, in this case, I've defined 3 states (sum1, sum2, and result) and 2 extra functions, handleResult and handleClear, which I could guess from your code.
export default function App() {
const [sum1, setSum1] = React.useState(0);
const [sum2, setSum2] = React.useState(0);
const [result, setResult] = React.useState(sum1 sum2);
const handleCalculate = () => {
setResult( sum1 sum2);
}
const handleClear = () => {
setResult(0);
setSum1(0);
setSum2(0);
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
Sum1: <input type="number" onChange={e => setSum1(e.target.value)} value={sum1}/> <br/>
Sum2: <input type="number" onChange={e => setSum2(e.target.value)} value={sum2}/> <br/>
<button onClick={handleCalculate}>Calculate</button>
<button onClick={handleClear}>Clear</button>
<h2>Result: {result}</h2>
<h3>Interactive: { sum1 sum2}</h3>
</div>
);
}
CodePudding user response:
function App() {
const [buttonText, setButtonText] = useState("InitialValue");
const [sum1, setSum1] = useState(0);
const [sum2, setSum2] = useState(0);
const handleClick = (props) =>{
setButtonText(props.target.value)
let inputText = document.getElementById('result').value;
console.log(inputText buttonText);
let total = inputText buttonText;
if (total.charAt(0) === "0") {
} else {
document.getElementById("result").value = total;
}
if (props.target.value === "clear") {
document.getElementById("result").value = "";
}
if (props.target.value === " ") {
setSum1(parseFloat(document.getElementById("result").value));
// alert(sum1);
document.getElementById("result").value = "";
}
if (props.target.value === "=") {
alert(sum1);
setSum2(parseFloat(document.getElementById("result").value))
document.getElementById("result").innerText = sum1 sum2;
}
return total;
}
return(
///my code
)
please try this now.