I’m new to react and I honestly can’t understand conditional rendering. I have one useState and one useReducer:
const [Trivia, setTrivia] = useState("Nothing")
const [{ currentOperand, previousOperand, Operation }, dispatch] = useReducer(reducer, {})
Following tutorials, I made a calculator with currentOperand, previousOperand, Operation and every time the currentOperand is 10, I want trivia to be “something”. I honestly don’t understand, since I don’t get any errors. I tried this:
const CheckEqual = () => {
if (currentOperand === 10) {
return (
<h4>
{setTrivia("Yes!")}
</h4>
)
} else {
return (
<h4>
{Trivia}
</h4>
)
}
}
and this
<div> { CheckEqual() } </div>
but nothing appears. Not even errors. Any help? Full code:
import React, { useReducer, useState, useEffect } from "react"
import DigitButton from "./DigitButton"
import OperationButton from "./OperationButton"
import "./styles.css"
export const actionsPossible = {
add_: "add",
operation_: "operation",
clear_: "clear",
delete_: "delete",
equal_: "equal",
}
function reducer(state, { type, payload }) {
switch (type) {
case actionsPossible.add_: //add
if (state.overwrite) {
return {
...state,
currentOperand: payload.digit,
overwrite: false,
}
}
if (payload.digit === "." && state.currentOperand == null) {
return state
}
if (payload.digit === "0" && state.currentOperand === "0") {
return state
}
if (payload.digit === "." && state.currentOperand.includes(".")) {
return state
}
return {
...state,
currentOperand: `${state.currentOperand || ""}${payload.digit}`,
}
case actionsPossible.clear_: //clear
{
return {}
}
case actionsPossible.operation_: //choosing operation
if (state.currentOperand == null && state.previousOperand == null) {
return state
}
if (state.currentOperand == null) {
return {
...state,
Operation: payload.Operation,
}
}
if (state.previousOperand == null) {
return {
...state,
Operation: payload.Operation,
previousOperand: state.currentOperand,
currentOperand: null,
}
}
return {
...state,
previousOperand: evaluate(state),
currentOperand: null,
operation_: payload.operation_,
}
case actionsPossible.equal_: //equal
{
if (state.Operation == null || state.currentOperand == null || state.previousOperand == null) {
return state
}
return {
...state,
overwrite: true,
previousOperand: null,
currentOperand: evaluate(state),
Operation: null,
}
}
case actionsPossible.delete_: //delete
{
if (state.overwrite) {
return {
...state,
overwrite: false,
currentOperand: null
}
}
if (state.currentOperand == null) {
return state
}
if (state.currentOperand.length === 1) {
return {
...state,
currentOperand: null
}
}
return {
...state,
currentOperand: state.currentOperand.slice(0, -1)
}
}
default: return state //default case
}
}
function evaluate({ currentOperand, previousOperand, Operation }) {
const previous = parseFloat(previousOperand)
const current = parseFloat(currentOperand)
if (isNaN(previous) || isNaN(current)) return ""
let computation = ""
switch (Operation) {
case "+":
computation = previous + current
break
case "-":
computation = previous - current
break
case "*":
computation = previous * current
break
case "÷":
computation = previous / current
break
default:
return
}
return computation.toString()
}
function App() {
const [Trivia, setTrivia] = useState("")
const [theme, setTheme] = useState("light")
const [{ currentOperand, previousOperand, Operation }, dispatch] = useReducer(reducer, {})
useEffect(() => {
if (currentOperand === 10) {
setTrivia("Yes!");
}
else {
setTrivia("Nothing");
}
}, [currentOperand])
return (
<div className="calculator-grid">
<div className="output">
<div className="previous-operand">{formatOperand(previousOperand)} {Operation}</div>
<div className="current-operand">{formatOperand(currentOperand)}</div>
</div>
<button className="span-two" onClick={() => dispatch({ type: actionsPossible.clear_ })}>AC</button>
<button onClick={() => dispatch({ type: actionsPossible.delete_ })}>DEL</button>
<OperationButton Operation="÷" dispatch={dispatch} />
<DigitButton digit="1" dispatch={dispatch} />
<DigitButton digit="2" dispatch={dispatch} />
<DigitButton digit="3" dispatch={dispatch} />
<OperationButton Operation="*" dispatch={dispatch} />
<DigitButton digit="4" dispatch={dispatch} />
<DigitButton digit="5" dispatch={dispatch} />
<DigitButton digit="6" dispatch={dispatch} />
<OperationButton Operation="+" dispatch={dispatch} />
<DigitButton digit="7" dispatch={dispatch} />
<DigitButton digit="8" dispatch={dispatch} />
<DigitButton digit="9" dispatch={dispatch} />
<OperationButton Operation="-" dispatch={dispatch} />
<DigitButton digit="." dispatch={dispatch} />
<DigitButton digit="0" dispatch={dispatch} />
<button className="span-two" onClick={() => dispatch({ type: actionsPossible.equal_ })}>=</button>
{/*----------------------------------TRIVIA--------------------------------*/}
<div className="count">
<h1>Random Trivia</h1>
<h2>(it will randomly pop up the more you use the calculator)</h2>
<h4>{Trivia}</h4>
</div>
</div>
);
}
export default App;
Advertisement
Answer
In your component, use useEffect() to mutate Trivia‘s value when currentOperand was mutated.
Then just use Trivia to display in return
like
const [Trivia, setTrivia] = useState("Nothing")
const [{ currentOperand, previousOperand, Operation }, dispatch] = useReducer(reducer, {})
useEffect(()=>{
if (currentOperand === 10) {
setTrivia("Yes!");
}
else {
setTrivia("Nothing");
}
}, [currentOperand])
return <>
{Trivia}
</>
Update [2022/09/05]
Assume your reducer works fine.
Then these code maybe can help When the currentOperand === 10, the Trivia changed
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
function App() {
const [Trivia, setTrivia] = React.useState("Nothing")
const [currentOperand, setCurrentOperand] = React.useState(0);
React.useEffect(()=>{
if (currentOperand === 10) {
setTrivia("Yes!");
}
else {
setTrivia("Nothing");
}
}, [currentOperand])
const handleClick = () =>{
setCurrentOperand(currentOperand+1)
}
return <div>
<button onClick={handleClick}>Add currentOperand</button>
<div>{Trivia}</div>
<div>{currentOperand}</div>
</div>
}
</script>
<script type="text/babel">
ReactDOM.render(
<App></App>
, document.getElementById("root"));
</script>