skip to Main Content

I have a simple page that has two parts: a label that displays 50% of the time after a page load, and a ‘Roll’ button that simulates the result of rolling a six sided die. Both of these parts use a d6 function that uses Math.Random.

These should be independent parts. Pressing the Roll button should not affect whether ‘hello’ is displayed or not, but that’s what happens. Pressing the Roll button will often make ‘hello’ appear and disappear. Why does this happen, and how can I stop it?

Code Sandbox here: https://codesandbox.io/p/sandbox/summer-monad-457k9j?file=%2Fsrc%2FApp.tsx%3A5%2C1-35%2C2

export default function App() {
  const [dieRollResult, setDieRollResult] = useState<number>(0);

  const die = (size: number): number => {
    return Math.floor(Math.random() * size) + 1;
  };

  const d6 = () => die(6);

  const shouldLabelBeVisible = () => (d6() <= 3 ? "visible" : "hidden");

  return (
    <Stack>
      <Typography visibility={shouldLabelBeVisible}>hello</Typography>
      <Typography>{dieRollResult}</Typography>
      <Button
        onClick={() => {
          setDieRollResult(d6());
        }}
      >
        Roll
      </Button>
    </Stack>
  );
}

2

Answers


  1. First the MUI Typography component doesn’t directly support a visibility prop. I also want to understand why you use shouldLabelBeVisible in the hello part ? do you want it to be visible if the number is inferior or equal to 3 ? if so i tried a console.log but the it doesn’t seem to match, like it’s random any number could be visible or hidden.

    Login or Signup to reply.
  2. When you click the button => setDieRollResult to a different value => trigger a rerender => const shouldLabelBeVisible = () => (d6() <= 3 ? "visible" : "hidden"); is re-caculated => shouldLabelBeVisible get a new value => the text "hello" change it visibility

    What you should do here is to make use of useMemo hook with the dependencies is an empty array (to say that run only one time)

    import "./styles.css";
    import { Button, Stack, Typography } from "@mui/material";
    import { useState, useMemo } from "react";
    
    const die = (size: number): number => {
      return Math.floor(Math.random() * size) + 1;
    };
    
    const d6 = () => die(6);
    
    export default function App() {
      const [dieRollResult, setDieRollResult] = useState<number>(0);
    
      const shouldLabelBeVisible = useMemo(() => {
        return d6() <= 3 ? "visible" : "hidden";
      }, []);
    
      return (
        <Stack>
          <Typography visibility={shouldLabelBeVisible}>hello</Typography>
          <Typography>{dieRollResult}</Typography>
          <Button
            onClick={() => {
              setDieRollResult(d6());
            }}
          >
            Roll
          </Button>
        </Stack>
      );
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search