簡體   English   中英

如何使用 React Hooks 實現單選按鈕的檢查所有按鈕?

[英]How to implement a check all button for radio buttons, using React Hooks?

不要與檢查頁面上的每個單選按鈕混淆。 我想實現一個check all button ,將嵌套 object state 的值設置為某個值。 我將每個問題存儲在嵌套的 state 中。 前任。

formQuestions({ 
  kitchen: [question,question2,question3],
  living: [question,question2,question3]
})

每個問題都制作了四個單選按鈕。 現在一次只能選擇一個單選按鈕。 每個單選按鈕都有自己的值。 前任。 `“好”、“一般”、“差”、“不適用”。

選擇單按鈕時,state是為該部分和問題動態生成的。 前任。

formAnswers({
  kitchen: {
    question: "Good"
    question2: "Poor"
  }
})

這里的目標是我要創建的按鈕,它只檢查每個問題 Ex 的一個值。 點擊按鈕question: "Good", question2: "Good"等。

對我來說,將 state 設置為動態值,我需要“Section name”讓我們稱之為Name和“Question”我們稱之為question 這將使我能夠像這樣訪問值formAnswers[Name][question]: value

我正在嘗試從名為 SectionHeader 的組件中設置SectionHeader 這些包含按鈕。

SectionHeader.js

import { FormAnswersContext, FormQuestionsContext } from "../../Store";

function SectionHeader({ title, name }) {
  const [formAnswers, setFormAnswers] = useContext(FormAnswersContext);
  const [formQuestions, setFormQuestions] = useContext(FormQuestionsContext);

  return (
    <div>
      <h1 className={styles["Header"]}>{title}</h1>
      <div className={styles["MarkAllWrapper"]}>
        <button className={styles["MarkAll"]}>
          Mark all items as "Good" in this section
        </button>
        <br />
        <button className={styles["MarkAll"]}>
          Mark all items as "N/A" in this section
        </button>
      </div>
    </div>
  );
}

Section Header的父級和表單代碼的 rest不包括我已經解釋的子單選按鈕,位於另一個組件LivingRoom.js

客廳.js

import { FormQuestionsContext, FormAnswersContext } from "../../Store";

function LivingRoomForm({ Name }) {
  const [expanded, setExpanded] = useState(false);
  const [formQuestions, setFormQuestions] = useContext(FormQuestionsContext);
  const [formAnswers, setFormAnswers] = useContext(FormAnswersContext);
  const array = formQuestions.living;
  const onChange = (e, name) => {
    const { value } = e.target;
    setFormAnswers((state) => ({
      ...state,
      [Name]: { ...state[Name], [name]: value },
    }));
  };
  const handleOpen = () => {
    setExpanded(!expanded);
  };
  return (
    <div>
      <Button
        className={styles["CollapseBtn"]}
        onClick={handleOpen}
        style={{ marginBottom: "1rem", width: "100%" }}
      >
        <p>LIVING ROOM INSPECTION</p>
        <FontAwesome
          className="super-crazy-colors"
          name="angle-up"
          rotate={expanded ? null : 180}
          size="lg"
          style={{
            marginTop: "5px",
            textShadow: "0 1px 0 rgba(0, 0, 0, 0.1)",
          }}
        />
      </Button>
      <Collapse className={styles["Collapse"]} isOpen={expanded}>
        <Card>
          <CardBody>
            {array ? (
              <div>
                <SectionHeader title="Living Room Inspection" name={Name} />
                <div
                  className={styles["LivingRoomFormWrapper"]}
                  id="living-room-form"
                >
                  {array.map((question, index) => {
                    const selected =
                      formAnswers[Name] && formAnswers[Name][question]
                        ? formAnswers[Name][question]
                        : "";
                    return (
                      <div className={styles["CheckboxWrapper"]} key={index}>
                        <h5>{question}</h5>
                        <Ratings
                          section={Name}
                          question={question}
                          onChange={onChange}
                          selected={selected}
                        />
                      </div>
                    );
                  })}
                </div>
                <br />
                <ImageUploader name="living" title={"Living Room"} />
              </div>
            ) : (
              <div></div>
            )}
          </CardBody>
        </Card>
      </Collapse>
    </div>
  );
}

如果有什么我想念的,請告訴我,我很樂意分享。 干杯

編輯:適用於需要單選按鈕組件的任何人。

Ratings.js

import React from "react";
import { FormGroup, CustomInput } from "reactstrap";

function Ratings({ selected, section, question, onChange }) {
  return (
    <div>
      <FormGroup>
        <div>
          <CustomInput
            checked={selected === "Good"}
            onChange={(e) => onChange(e, question)}
            type="radio"
            id={`${section}_${question}_Good`}
            value="Good"
            label="Good"
          />
          <CustomInput
            checked={selected === "Fair"}
            onChange={(e) => onChange(e, question)}
            type="radio"
            id={`${section}_${question}_Fair`}
            value="Fair"
            label="Fair"
          />
          <CustomInput
            checked={selected === "Poor"}
            onChange={(e) => onChange(e, question)}
            type="radio"
            id={`${section}_${question}_Poor`}
            value="Poor"
            label="Poor"
          />
          <CustomInput
            checked={selected === "N/A"}
            onChange={(e) => onChange(e, question)}
            type="radio"
            id={`${section}_${question}_NA`}
            value="N/A"
            label="N/A"
          />
        </div>
      </FormGroup>
    </div>
  );
}

我不完全理解你的問題,很抱歉,但我認為這會對你有所幫助。 這是使用反應的單選按鈕的實現 -

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  handleChange = e => {
    const { name, value } = e.target;

    this.setState({
      [name]: value
    });
  };

  render() {
    return (
      <div className="radio-buttons">
        Windows
        <input
          id="windows"
          value="windows"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
        Mac
        <input
          id="mac"
          value="mac"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
        Linux
        <input
          id="linux"
          value="linux"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
      </div>
    );
  }
}

經過幾次嘗試,我能夠找出解決此問題的方法。

這里的關鍵是想辦法收集每個問題,以便在設置 state 時將其用作關鍵。 由於我的問題存儲在 ContextAPI 中,因此我能夠像這樣將它們拉出來......

這可能不是最好的解決方案,但它對我有用。

  const setStateGood = () => {
    formQuestions[name].map((question) => {
      setFormAnswers((state) => ({
        ...state,
        [name]: { ...state[name], [question]: "Good" },
      }));
    });
  };
  const setStateNA = () => {
    formQuestions[name].map((question) => {
      setFormAnswers((state) => ({
        ...state,
        [name]: { ...state[name], [question]: "N/A" },
      }));
    });
  };

我能夠通過每個問題 map ,因為name正在通過道具是實際 object 中的一個鍵, formQuestions[name] 因為我正在映射每個問題,所以我可以將該問題設置為一個鍵,並將每個問題的新 state 返回到我想要的任何問題。

但是,如果我要創建一個onClick={setState('Good')} ,React 不喜歡這樣,它會創建一個無限循環。 如果我找到一個,我會尋找更多的解決方案並更新這篇文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM