简体   繁体   English

ReactJS:如何在页面重新加载时保持选中/选中我的复选框和单选按钮?

[英]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.

相关问题 如何使用php在下一页上保持选中单选按钮? - How do I keep checked radio button on the next page with php? 保持选中的单选按钮选中并在页面刷新时单击? - Keep the selected radio button checked and clicked upon page refresh? 我的 if 语句不起作用,为什么单选按钮在我重新加载页面后仍然选中? - my if statement not work, and why radio button still checked after i reload the page? 如何在重新加载页面时保持复选框处于选中状态并显示内容? - How to keep checkbox checked and content shown when reload page? 如果页面刷新,如何保持选中单选按钮 - How to keep the radio button selected if the page is refreshed 页面刷新后如何保持单选按钮选中? - how to keep radio button checked after page refresh? 如何检查我的单选按钮是否已选中并且循环正常工作? - How do I check if my radio button is selected and the loop is working? JavaScript:提交表单后,如何保持单选按钮处于选中状态? - JavaScript: How do I keep a radio button checked after form submit? React.js - 如何设置选中/选中的单选按钮并跟踪 onChange? - React.js - How do I set a checked/selected radio button and track the onChange? Javascript:当选中/选中分配给它的单选按钮时,如何使输入/文本字段为必需字段? - Javascript: How do I make an input/text field mandatory(required) when the radio button assigned to it is checked/selected?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM