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
<a href={pdf} target="_blank" rel="noreferrer">
<span className="underlineLink">
{" "}
Erstinformationen für Versicherungsmakler gemäß §15
VersVerm
</span>
</a>
die 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
<span className="underlineLink">
{" "}
Erstinformationen für Versicherungsmakler gemäß §15 VersVerm
</span>
die 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.