[英]ReactJS: How do I keep my checkbox and radio button checked/selected on page reload?
I have my radio buttons and checkboxes from material UI and they work as expected.我有来自 Material UI 的单选按钮和复选框,它们按预期工作。 Data is stored is state and local storage correctly and is persisted correctly too.数据存储为 state,本地存储正确,并且也正确保存。 I have a multistep form and my issues is that, when I select the radio button or checkbox and move to the next page then come back, my selections appear "not selected", like the checkboxes are not checked and radio button selected is not filled even though they are and data is stored correctly in state and local storage persists the selections.我有一个多步骤表单,我的问题是,当我 select 单选按钮或复选框并移动到下一页然后返回时,我的选择显示为“未选中”,就像未选中复选框和未选中单选按钮一样即使它们是并且数据正确存储在 state 中并且本地存储保留了选择。 How do I keep my selections selected and appear to the user correctly?如何让我的选择保持选中状态并正确显示给用户?
Here is one of the radio button pages:这是单选按钮页面之一:
import React, { useContext, useEffect, useState } from "react";
import { Global } from "../../../shared/utilities/scripts/global.context";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import Radio from "@mui/material/Radio";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import "./nanny.complete.profile.css";
const radioStyle = {
color: "#9695b9",
"&.Mui-checked": {
color: "#9695b9",
},
};
const Radius = () => {
//to translate page
const { t } = useTranslation();
const { radioSelected, setRadioSelected } = useContext(Global);
const { values, setValues } = useContext(Global);
const [disabled, setDisabled] = useState(true);
//get state from localStorage to persist
useEffect(() => {
const localState = JSON.parse(localStorage.getItem("values"));
if (values.radius === "") {
setValues((values) => ({ ...values, ...localState }));
}
}, []);
useEffect(() => {
const localDisabled = JSON.parse(localStorage.getItem("disabled"))
if(values.radius === "") {
setDisabled(localDisabled)
}else {
setDisabled(!localDisabled)
}
})
//setting localStorage
useEffect(() => {
localStorage.setItem("values", JSON.stringify(values));
}, [values.radius]);
useEffect(() => {
localStorage.setItem("disabled", JSON.stringify(disabled));
}, []);
const handleRadio = (e) => {
const { name, value } = e.target;
setRadioSelected(value);
setValues({
...values,
[name]: value,
});
};
const controlProps = (item) => ({
checked: radioSelected === item,
onChange: handleRadio,
value: item,
name: "radius",
inputProps: { "aria-label": item },
});
return (
<div className="sub-settings-div">
<Link className="back" to="/vaccination">
<span>
<ArrowBackIcon />
</span>
Back
</Link>
<h3 className="sub-settings-header">{t("common.title")}</h3>
<h2 className="sub-settings-sub-header">{t("radius.subTitle")}</h2>
<div className="radio-container">
<div className="radio-item">
<Radio
className="radio"
sx={radioStyle}
{...controlProps("0-5 km")}
/>
<div className="labels">
<label className="label">
0-5 km
<p>
{" "}
{`(${t("radius.car")}: 5-10 mins / ${t(
"radius.bike"
)}: 15-20 mins)`}
</p>
</label>
</div>
</div>
<div className="radio-item">
<Radio
className="radio"
sx={radioStyle}
{...controlProps("5-10 km")}
/>
<div className="labels">
<label className="label">
5-10 km
<p>
{" "}
{`(${t("radius.car")}: 10-20 mins / ${t(
"radius.bike"
)}: 20-35 mins)`}
</p>
</label>
</div>
</div>
<div className="radio-item">
<Radio
className="radio"
sx={radioStyle}
{...controlProps("10-20 km")}
/>
<div className="labels">
<label className="label">
10-20 km
<p>
{" "}
{`(${t("radius.car")}: 20-30 mins / ${t(
"radius.bike"
)}: 35-50 mins)`}
</p>
</label>
</div>
</div>
<div className="radio-item">
<Radio
className="radio"
sx={radioStyle}
{...controlProps("20-50 km")}
/>
<div className="labels">
<label className="label">
20-50 km
<p>
{" "}
{`(${t("radius.car")}: 30-60 mins > ${t("radius.recommend")})`}
</p>
</label>
</div>
</div>
</div>
<div className="nav-btns">
<Link to="/vaccination" className="prev-link">
<button className="prev">{t("buttons.back")}</button>
</Link>
<Link to="/booked" className="next-link">
<button disabled = {disabled ? true : false} className={disabled ? "disabled" : "next"}>
{t("buttons.next")}
<span>
<ArrowForwardIcon />
</span>
</button>
</Link>
</div>
</div>
);
};
export default Radius;
And one of the pages with checkboxes:其中一个带有复选框的页面:
import React, { useContext, useEffect, useState } from "react";
import { Global } from "../../../shared/utilities/scripts/global.context";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import Checkbox from "@mui/material/Checkbox";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import "./nanny.complete.profile.css";
const checkboxStyle = {
color: "#9695b9",
"&.Mui-checked": {
color: "#9695b9",
},
};
const AgeRange = () => {
//to translate page
const { t } = useTranslation();
//state from context API
const { values, setValues } = useContext(Global);
const [disabled, setDisabled] = useState(true);
//get state from localStorage to persist
useEffect(() => {
const localState = JSON.parse(localStorage.getItem("values"));
if (values.ageRange.length === 0) {
setValues((values) => ({ ...values, ...localState }));
}
}, []);
useEffect(() => {
const localDisabled = JSON.parse(localStorage.getItem("disabled"))
if(values.ageRange.length === 0) {
setDisabled(localDisabled)
console.log(disabled)
}else {
setDisabled(!localDisabled)
}
})
//setting localStorage
useEffect(() => {
localStorage.setItem("values", JSON.stringify(values));
}, [values.ageRange]);
useEffect(() => {
localStorage.setItem("disabled", JSON.stringify(disabled));
}, []);
//handle checkbox selection
const handleSelect = (e) => {
const { id } = e.target;
let newSelected = [...values.ageRange, id];
if (values.ageRange.includes(id)) {
newSelected = newSelected.filter((choice) => choice !== id);
}
setValues({
...values,
ageRange: newSelected,
});
};
return (
<div className="sub-settings-div">
<Link className="back" to="/hourly-rate">
<span>
<ArrowBackIcon />
</span>
Back
</Link>
<h3 className="sub-settings-header">{t("common.title")}</h3>
<h2 className="sub-settings-sub-header">{t("ageRange.subTitle")}</h2>
<div className="checkbox-container">
<div className="checkbox">
<Checkbox
className="check"
sx={checkboxStyle}
id="babies"
onChange={handleSelect}
/>
<label className="label" htmlFor="babies">
{t("ageRange.babies")} <span>{`(0-1 ${t("ageRange.years")})`}</span>
</label>
</div>
<div className="checkbox">
<Checkbox
className="check"
sx={checkboxStyle}
id="infants"
onChange={handleSelect}
/>
<label className="label" htmlFor="infants">
{t("ageRange.infants")}{" "}
<span>{`(1-3 ${t("ageRange.years")})`}</span>
</label>
</div>
<div className="checkbox">
<Checkbox
className="check"
sx={checkboxStyle}
id="playschool"
onChange={handleSelect}
/>
<label className="label" htmlFor="playschool">
{t("ageRange.playschool")}{" "}
<span>{`(3-6 ${t("ageRange.years")})`}</span>
</label>
</div>
<div className="checkbox">
<Checkbox
className="check"
sx={checkboxStyle}
id="mini"
onChange={handleSelect}
/>
<label className="label" htmlFor="mini">
{t("ageRange.mini")} <span>{`(6-10 ${t("ageRange.years")})`}</span>
</label>
</div>
<div className="checkbox">
<Checkbox
className="check"
sx={checkboxStyle}
id="maxi"
onChange={handleSelect}
/>
<label className="label" htmlFor="maxi">
{t("ageRange.maxi")} <span>{`(10-14 ${t("ageRange.years")})`}</span>
</label>
</div>
</div>
<div className="nav-btns">
<Link to="/hourly-rate" className="prev-link">
<button className="prev">{t("buttons.back")}</button>
</Link>
<Link to="/car" className="next-link">
<button disabled = {disabled ? true : false} className={disabled ? "disabled" : "next"}>
{t("buttons.next")}
<span>
<ArrowForwardIcon />
</span>
</button>
</Link>
</div>
</div>
);
};
export default AgeRange;
Any help would truly be appreciated.任何帮助将不胜感激。
1. Method一、方法
You can store bool value to localstorage as soon as the checkbox or radio is been selected.一旦选中复选框或单选按钮,您就可以将 bool 值存储到本地存储。 Get the values from localStorage and check with bool value if its true make it as checked.从 localStorage 获取值并检查 bool 值是否为 true 是否已选中。
<Checkbox
className="check"
sx={checkboxStyle}
id="infants"
onChange={handleSelect}
checked = { values.isCheckboxSelected ? true : false}
// you can replace isCheckboxSelected name with your own choise
/>
2. Method If you are using redux then we have library called redux-persist which stores all your state data to localstorage so you can easily persist all the state values. 2. 方法如果您使用的是redux ,那么我们有一个名为redux-persist的库,它将所有 state 数据存储到本地存储,因此您可以轻松地保留所有 state 值。
https://www.npmjs.com/package/redux-persist https://www.npmjs.com/package/redux-persist
Below is how i am using in one of my APP以下是我在我的一个应用程序中的使用方式
<StyledInputField
name="above25Years"
value={checkout.above25Years}
onChange={(e) => dispatch(setAbove25Years(true))}
type="radio"
checked={checkout.above25Years ? true : false}
width={'25px'}
height={'25px'}
/> Yes
Since you already using react context, you already one step closer to persisting your values.由于您已经在使用 React 上下文,因此您离坚持您的价值观又近了一步。
You need to do some correction to your codes您需要对代码进行一些更正
//get state from localStorage to persist
useEffect(() => {
const localValues = JSON.parse(localStorage.getItem("values"));
setValues(localValues)
}, []);
//save to localStorage
useEffect(() => {
localStorage.setItem('values', JSON.stringify(values));
}, [values])
Any values that uses setValue from your GlobalContext will be persist to your localStorage.使用 GlobalContext 中的 setValue 的任何值都将保留到您的 localStorage。
Since you already persisting the state in your context provider, you can remove the localStorage codes in your AgeRange
component so there is only a single source of truth, else they will be overwriting each other.由于您已经在上下文提供程序中保留了 state,因此您可以删除AgeRange
组件中的 localStorage 代码,这样只有一个真实来源,否则它们将相互覆盖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.