ReactJS:如何在页面重新加载时选中复选框和单选按钮



我有来自材质UI的单选按钮和复选框,它们可以按预期工作。数据的存储是正确的状态和本地存储,并且也正确地持久化。我有一个多步骤的表单,我的问题是,当我选择单选按钮或复选框并移动到下一页然后返回时,我的选择会出现";如果"未选择";,就像复选框没有被选中,单选按钮被选中也没有被填充一样,即使它们被选中了,数据也被正确地存储在状态中,并且本地存储会保持选择。如何保持所选内容处于选中状态并正确显示在用户面前?

这是其中一个单选按钮页面:

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;

其中一个带有复选框的页面:

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;

任何帮助都将不胜感激。

1。方法

一旦选中复选框或单选框,就可以将布尔值存储到本地存储。从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.方法如果您使用redu,那么我们有一个名为redux-persistent的库,它将您的所有状态数据存储到本地存储中,这样您就可以轻松地持久化所有状态值。

https://www.npmjs.com/package/redux-persist

以下是我在一个应用程序中的使用情况

<StyledInputField
name="above25Years"
value={checkout.above25Years}
onChange={(e) => dispatch(setAbove25Years(true))}
type="radio"
checked={checkout.above25Years ? true : false}
width={'25px'}
height={'25px'}
/> Yes 

由于您已经使用了react上下文,因此离持久化您的值又近了一步。

你需要对你的代码做一些更正

//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])

任何使用GlobalContext中的setValue的值都将保留到本地存储中。

由于您已经在上下文提供程序中持久化了状态,因此可以删除AgeRange组件中的localStorage代码,这样就只有一个真相来源,否则它们将相互覆盖。

最新更新