HyperOni
HyperOni

Reputation: 173

How do I make a text appear based on a condition in react useState?

I'm new to react and I'm trying to learn it. So far, with tutorials and so on, I made a computer with a light and day mode. I want to add a div on the right side where text will appear based on conditions, like: if the output is over 9000, a message with appear like "its over 9000!" and so on. I want to add multiple text sentences based on different conditions. I've tried but I keep getting errors like undefined, state is a const, etc. What's the best way to do this using useState?

//imports

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 formatOperand(operand) {
  // format so 1000 can be 1,000
}
function App() {

  //const [Trivia, setTrivia] = useState("")
  const [theme, setTheme] = useState("light")
  const [{ currentOperand, previousOperand, Operation }, dispatch] = useReducer(reducer, {})
  const toggleTheme = () => {
    setTheme((curr) => (curr === "light" ? "dark" : "light"))
  }

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <div id={theme}>
        <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>
          {/*----------------------------------TOGGLE BTN--------------------------------*/}
  //toggle button code, not important
        {/*----------------------------------TRIVIA--------------------------------*/}
        <div className="count">
          <h1>Random Trivia</h1>
          <h4>{Trivia}</h4>
          {/*   <h4>{Trivia2}</h4>   */}
          {/*   <h4>{Trivia3}</h4>   */}
          {/*   <h4>{Trivia4}</h4>   */}

        </div>
      </div>
    </ThemeContext.Provider>

  );
}

export default App;

Upvotes: 0

Views: 1107

Answers (1)

shantr
shantr

Reputation: 804

Basic conditional rendering follow this syntax

const Component = ({ ... }) => {
  ...
  return (
    <div>
      {Boolean(value) && <ComponentToRenderIfTrue />}
    </div>
  );
}

Then a very basic example of having several possible trivia would look like

const Component = ({ ... }) => {
  ...
  return (
    <div>
      {currentOperand === 1 && <span>Trivia 1</span>} // only rendered if currentOperand === 1 else ignored
      {currentOperand === 2 && <span>Trivia 2</span>} // only rendered if currentOperand === 2 else ignored
      {currentOperand === 3 && <span>Trivia 3</span>} // only rendered if currentOperand === 3 else ignored
      {currentOperand === 4 && <span>Trivia 4</span>} // etc
      {currentOperand === 5 && <span>Trivia 5</span>}
    </div>
  );
}

Another less verbose way would be to simply compute a trivia value using useMemo

const Component = ({ ... }) => {
  ...
  const trivia = useMemo(() => {
    switch (operand) {
      case 1: return 'Trivia 1';
      case 2: return 'Trivia 2';
      case 3: return 'Trivia 3';
      case 4: return 'Trivia 4';
      default:
        return null;
    }
  }, [operand]);
  return (
    <div>
      {Boolean(trivia) && <span>{trivia}</span>}
    </div>
  );
}

The more precise explanation of how conditional rendering work is that when you provide a boolean value in the rendering, the React engine will actually ignore it

const Component = () => {
  return (
    <div>
      {false} // will be ignored by react engine
    </div>
  );
}

In js true && 'hello world' simply resolve to the string 'hello world' while false && 'hello world' resolve to the boolean false

Then

const Component = () => {
  return (
    <div>
      {true && <span>hello world</span>}
    </div>
  );
}

is actually the same as

const Component = () => {
  return (
    <div>
      <span>hello world</span>
    </div>
  );
}

If you put things together you should understand how {Boolean(value) && <Component/>} might either be ignored by react engine if Boolean(value) is false or render if Boolean(value) is true

Upvotes: 1

Related Questions