Home > database >  how can i reduce my useState code and validate with onChange?
how can i reduce my useState code and validate with onChange?

Time:08-26

I'd like to reduce my code, but don't know how.

The first three checkboxes will enable the button (therefore i need the validation), the last two checkboxes data will be send to the parent component.

How can I reduce const [checkValue1, setCheckValue1] = useState(false); x 5 to one get the true/false data with onChange to validate. Is it possible to .map the checkboxes?

thx


import React from "react";
import { Checkbox } from "@mui/material";
import { green } from "@mui/material/colors";
import { red } from "@mui/material/colors";
import { useState, useEffect } from "react";
import pdf from "../../documents/erstinformation.pdf";

function Permission(props) {

  //checkboxes Values
  const [checkValue1, setCheckValue1] = useState(false);
  const [checkValue2, setCheckValue2] = useState(false);
  const [checkValue3, setCheckValue3] = useState(false);
  const [checkValue4, setCheckValue4] = useState(false);
  const [checkValue5, setCheckValue5] = useState(false);

 
// This  will enable/disable the botton 
  const [buttonState, setButtonState] = useState(true);


 // This  should be the onChange 
  function handleClick1() {
    if (checkValue1 == false) {
      setCheckValue1(true);
    } else {
      setCheckValue1(false);
    }
    checkButton();
  }
  function handleClick2() {
    if (checkValue2 == false) {
      setCheckValue2(true);
    } else {
      setCheckValue2(false);
    }
    checkButton();
  }
  function handleClick3() {
    if (checkValue3 == false) {
      setCheckValue3(true);
    } else {
      setCheckValue3(false);
    }
    checkButton();
  }
  function handleClick4() {
    if (checkValue4 == false) {
      setCheckValue4(true);
    } else setCheckValue4(false);
  }
  function handleClick5() {
    if (checkValue5 == false) {
      setCheckValue5(true);
    } else setCheckValue5(false);
  }


  // This validates, if the three checkboxes are clicked to disable/enable the botton
  function checkButton() {
    if (checkValue1 === true && checkValue2 === true && checkValue3 === true) {
      setButtonState(false);
    } else {
      setButtonState(true);
    }
  }

  // This will double check, if validation is correct and send data to parent component
  function handleSubmit() {
    if (checkValue1 === true && checkValue2 === true && checkValue3 === true) {
      props.sendShowPermission(false);
      props.sendShowFormForRequest(true);
    } else {
      alert("die notwendigen Haken setzen!");
    }
  }
  
// this updates  values immideatly
  useEffect(() => {
    checkButton();
  }, [checkValue1, checkValue2, checkValue3, checkValue4, checkValue5]);

  //HTML Stuff
  return (
    <>
     
        <div>
          Allgemeine Informationen
          <div className="checkbox-div">
            <div>
              <div>
                <Checkbox
                  sx={{
                    color: red[200],
                    "&.Mui-checked": {
                      color: green[800],
                    },
                  }}
                  checked={checkValue1}
                  onClick={handleClick1}
                />
              </div>
              <div display="flex">
                <p>
                  Ich bestätige, die&nbsp;
                  <a href={pdf} target="_blank" rel="noreferrer">
                    <span className="underlineLink">
                      {" "}
                      Erstinformationen für Versicherungsmakler gemäß §15
                      VersVerm
                    </span>
                  </a>
                  die&nbsp; gelesen zu haben.
                </p>
              </div>
            </div>
            <div>
              <div>
                <Checkbox
                  sx={{
                    color: red[200],
                    "&.Mui-checked": {
                      color: green[800],
                    },
                  }}
                  checked={checkValue2}
                  onClick={handleClick2}
                />
              </div>
              <div>
                <p>
                  Ich bestätige, den
                  <a href="" target="_blank" rel="noreferrer">
                    {" "}
                    <span className="underlineLink">
                      Beratungs- und Dokumentationsverzicht
                    </span>
                  </a>{" "}
                  gelesen zu haben und erkläre mich damit einverstanden. Ich bin
                  mir bewusst, dass dieser Verzicht sich negativ auf meine
                  Möglichkeit auswirkt, Schadenersatz gegen den
                  Versicherungsmakler gemäß § 63 VVG geltend zu machen.
                </p>
              </div>
            </div>
            <div>
              <div>
                <Checkbox
                  sx={{
                    color: red[200],
                    "&.Mui-checked": {
                      color: green[800],
                    },
                  }}
                  checked={checkValue3}
                  onClick={handleClick3}
                />
              </div>
              <div>
                <p>
                  Ich habe die Hinweise zum
                  <a href="/privacy" target="_blank" rel="noreferrer">
                    <span className="underlineLink">
                      {" "}
                      Datenschutz zur Kenntnis genommen
                    </span>
                  </a>
                  .
                </p>
              </div>
            </div>
          </div>
          <div className="checkbox-div">
            <div> Ich möchte regelmäßige Updates erhalten</div>
            <div>
              {" "}
              <label htmlFor="">
                <Checkbox
                  sx={{
                    color: green[50],
                    "&.Mui-checked": {
                      color: green[800],
                    },
                  }}
                  checked={checkValue4}
                  onClick={handleClick4}
                />
                per Mail
              </label>
            </div>
            <div>
              <label htmlFor="">
                {" "}
                <Checkbox
                  sx={{
                    color: green[50],
                    "&.Mui-checked": {
                      color: green[800],
                    },
                  }}
                  checked={checkValue5}
                  onClick={handleClick5}
                />
                per WhatsApp
              </label>
            </div>
          </div>
          <div className="request-footer">
            <button
              disabled={buttonState}
              onClick={() => {
                handleSubmit();                
                props.sendPermissionWA(checkValue4)
                props.sendPermissionMail(checkValue5)
              }}
              className="btn btn-transparent"
            >
              Weiter
            </button>
          </div>
        </div>
      
    </>
  );
}

export default Permission;



CodePudding user response:

you can use just one state object and change it like this:

  const [values, setValues] = useState({
    checkValue1: false,
    checkValue2: false,
    checkValue3: false,
    checkValue4: false,
    checkValue5: false
  })

setValues({ ...values, checkValue1: true })

For the checkboxes, you can create a checkbox component and an array of objects to map over in order to assign the values to the component.

CodePudding user response:

This a great use-case for useReducer. A good mental check on whether or not you should apply useReducer is when you are finding yourself trying to couple state changes, and you are struggling to maintain their collaborative effort. If there are cascading changes that are dependent on multiple state changes, then tie them together. Here is a loose example of what you are trying to do. I removed the material-ui imports but the principles still stand.

Here is the sandbox: https://codesandbox.io/s/bold-field-wu6tcb?file=/src/App.js

And here is my code:

import "./styles.css";
import React, { useState, useReducer } from "react";

export default function App() {
  const initialCheckValues = {
    checkValue1: false,
    checkValue2: false,
    checkValue3: false,
    checkValue4: false,
    checkValue5: false
  };

  const [checkValues, dispatch] = useReducer(valueReducer, initialCheckValues);

  function valueReducer(state, action) {
    switch (action.type) {
      case "checkValue1":
        return { ...state, checkValue1: !state.checkValue1 };
      case "checkValue2":
        return { ...state, checkValue2: !state.checkValue2 };
      case "checkValue3":
        return { ...state, checkValue3: !state.checkValue3 };
      case "checkValue4":
        return { ...state, checkValue4: !state.checkValue4 };
      case "checkValue5":
        return { ...state, checkValue5: !state.checkValue5 };
    }
  }
  console.log(
    checkValues.checkValue1   " i am 1",
    checkValues.checkValue2   " i am 2",
    checkValues.checkValue3   " i am 3",
    checkValues.checkValue4   " i am 4",
    checkValues.checkValue5   " i am 5"
  );
  return (
    <>
      <div>
        Allgemeine Informationen
        <div className="checkbox-div">
          <div>
            <div>
              <input
                type="checkbox"
                checked={checkValues.check1}
                onClick={() => dispatch({ type: "checkValue1" })}
              />
            </div>
            <div display="flex">
              <p>
                Ich bestätige, die&nbsp;
                <span className="underlineLink">
                  {" "}
                  Erstinformationen für Versicherungsmakler gemäß §15 VersVerm
                </span>
                die&nbsp; gelesen zu haben.
              </p>
            </div>
          </div>
          <div>
            <div>
              <input
                type="checkbox"
                checked={checkValues.check2}
                onClick={() => dispatch({ type: "checkValue2" })}
              />
            </div>
            <div>
              <p>
                Ich bestätige, den
                <a href="" target="_blank" rel="noreferrer">
                  {" "}
                  <span className="underlineLink">
                    Beratungs- und Dokumentationsverzicht
                  </span>
                </a>{" "}
                gelesen zu haben und erkläre mich damit einverstanden. Ich bin
                mir bewusst, dass dieser Verzicht sich negativ auf meine
                Möglichkeit auswirkt, Schadenersatz gegen den
                Versicherungsmakler gemäß § 63 VVG geltend zu machen.
              </p>
            </div>
          </div>
          <div>
            <div>
              <input
                type="checkbox"
                checked={checkValues.check3}
                onClick={() => dispatch({ type: "checkValue3" })}
              />
            </div>
            <div>
              <p>
                Ich habe die Hinweise zum
                <a href="/privacy" target="_blank" rel="noreferrer">
                  <span className="underlineLink">
                    {" "}
                    Datenschutz zur Kenntnis genommen
                  </span>
                </a>
                .
              </p>
            </div>
          </div>
        </div>
        <div className="checkbox-div">
          <div> Ich möchte regelmäßige Updates erhalten</div>
          <div>
            {" "}
            <label htmlFor="">
              <input
                type="checkbox"
                checked={checkValues.check4}
                onClick={() => dispatch({ type: "checkValue4" })}
              />
              per Mail
            </label>
          </div>
          <div>
            <label htmlFor="">
              {" "}
              <input
                type="checkbox"
                checked={checkValues.check5}
                onClick={() => dispatch({ type: "checkValue5" })}
              />
              per WhatsApp
            </label>
          </div>
        </div>
        <div className="request-footer">Weiter</div>
      </div>
    </>
  );
}

By the way, you won't need useEffect here because as you'll see in the console, the inputs are dynamically updating. Your submit logic should be plug-and-play with this solution. This also gives you a more flexible solution moving forward, especially if you want to add more complexity to your forms. I would get familiar with useReducer because it's arguably one of the most powerful hooks React has to offer.

  • Related