Home > Blockchain >  How can I stop the conditional JSX changing in React until the submit is clicked again?
How can I stop the conditional JSX changing in React until the submit is clicked again?

Time:01-11

It's kind of tricky to explain it, that's why I recorded what's happening. enter image description here

As you can see, once I enter the incorrect answer and then use the input field again, I get the correct message without hitting submit. I know this should happen based on the code I've written, but I can't figure out a way to make it right.

Here's my code:

const AdditionMain = () => {
  const [sum, setSum] = useState("");

  const [isSubmit, setIsSubmit] = useState(false);
  const [disabled, setDisabled] = useState(false);
  const randomNum1 = () => {
    let number1 = Math.floor(Math.random() * 50);

    return number1;
  };
  const randomNum2 = () => {
    let number2 = Math.floor(Math.random() * 50);
    return number2;
  };
  const number1 = useMemo(() => randomNum1(), []);
  const number2 = useMemo(() => randomNum2(), []);
  const result = number1   number2;

  const correctAnswer = <Typography>Correct!</Typography>;
  const wrongAnswer = <Typography>Wrong!</Typography>;
  const enterAnswer = <Typography>Enter your answer!</Typography>;

  const onSubmit = (e) => {
    e.preventDefault();

    setIsSubmit((prevState) => !prevState);
    if (sum === result) {
      setDisabled(!disabled);
    }
  };

  return (
    <>
      <Navbar />
      <Card
        sx={{
          marginTop: 2,
          height: 50,
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
        }}
      >
        <Typography></Typography>
      </Card>
      <Container component="main" maxWidth="xs">
        <Box
          sx={{
            marginTop: 8,
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
          }}
        >
          <Typography>Fill in the box to make the equation true.</Typography>
          <Typography fontSize={28}>
            {number1}   {number2} =
          </Typography>

          <TextField
            inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
            onChange={(e) => setSum(parseInt(e.target.value))}
            disabled={disabled}
            type="number"
            value={sum}
            name="sum"
            id="outlined-basic"
            label=""
            variant="outlined"
          ></TextField>

          {!isSubmit || (isSubmit && sum === "") ? (
            <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant="outlined">
              Submit
            </Button>
          ) : isSubmit && sum !== result ? (
            <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant="outlined">
              {" "}
              Try again!
            </Button>
          ) : (
            () => {}
          )}

          {isSubmit && sum === ""
            ? enterAnswer
            : isSubmit && sum !== result
            ? wrongAnswer
            : isSubmit && sum === result
            ? correctAnswer
            : ""}
          {isSubmit && sum === result ? <Button>Try new one</Button> : () => {}}
        </Box>
      </Container>
    </>
  );
};

export default AdditionMain;

CodePudding user response:

Try to add a onNewTry method which enables the input field and clear the isSubmit flag:

const AdditionMain = () => {
  const [sum, setSum] = useState('');

  const [isSubmit, setIsSubmit] = useState(false);
  const [disabled, setDisabled] = useState(false);

  const randomNum1 = () => {
    let number1 = Math.floor(Math.random() * 50);

    return number1;
  };
  const randomNum2 = () => {
    let number2 = Math.floor(Math.random() * 50);
    return number2;
  };
  const number1 = useMemo(() => randomNum1(), []);
  const number2 = useMemo(() => randomNum2(), []);
  const result = number1   number2;

  const correctAnswer = <Typography>Correct!</Typography>;
  const wrongAnswer = <Typography>Wrong!</Typography>;
  const enterAnswer = <Typography>Enter your answer!</Typography>;

  const onNewTry = () => {
    setIsSubmit(false);
    setDisabled(false);
  }

  const onSubmit = (e) => {
    e.preventDefault();

    setIsSubmit(true);
    setDisabled(true);
  };

  return (
    <>
      <Navbar />
      <Card
        sx={{
          marginTop: 2,
          height: 50,
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
        }}
      >
        <Typography></Typography>
      </Card>
      <Container component='main' maxWidth='xs'>
        <Box
          sx={{
            marginTop: 8,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
          }}
        >
          <Typography>Fill in the box to make the equation true.</Typography>
          <Typography fontSize={28}>
            {number1}   {number2} =
          </Typography>

          <TextField
            inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
            onChange={(e) => setSum(parseInt(e.target.value))}
            disabled={disabled}
            type='number'
            value={sum}
            name='sum'
            id='outlined-basic'
            label=''
            variant='outlined'
          ></TextField>

          {!isSubmit || (isSubmit && sum === '') ? (
            <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant='outlined'>
              Submit
            </Button>
          ) : isSubmit && sum !== result ? (
            <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant='outlined'>
              {' '}
              Try again!
            </Button>
          ) : (
            () => {}
          )}

          {isSubmit && sum === ''
            ? enterAnswer
            : isSubmit && sum !== result
            ? wrongAnswer
            : isSubmit && sum === result
            ? correctAnswer
            : ''}
          {isSubmit && sum === result ? <Button type="button" onClick={onNewTry}>Try new one</Button> : () => {}}
        </Box>
      </Container>
    </>
  );
};

export default AdditionMain;

CodePudding user response:

Just set the value of isSubmit as false when using the input field by calling setIsSubmit(false) in onChange method of TextField like below

 ...
      <TextField
        inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
        onChange={(e) => {
                    setSum(parseInt(e.target.value));
                    setIsSubmit(false)
                 }}
        disabled={disabled}
        type="number"
        value={sum}
        name="sum"
        id="outlined-basic"
        label=""
        variant="outlined"
      ></TextField>
...
  • Related