Skip to content
Advertisement

React conditional rendering based on other state doesn’t work

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>
Advertisement