[英]How to implement a check all button for radio buttons, using React Hooks?
Don't get this confused with checking each radio button I have on the page.不要与检查页面上的每个单选按钮混淆。 I want to implement a
check all button
that sets the value of a nested object state equal to a certain value.我想实现一个
check all button
,将嵌套 object state 的值设置为某个值。 I am storing each question in a nested state.我将每个问题存储在嵌套的 state 中。 Ex.
前任。
formQuestions({
kitchen: [question,question2,question3],
living: [question,question2,question3]
})
Four radio buttons are being made for each question.每个问题都制作了四个单选按钮。 Now one radio button can only be selected at once.
现在一次只能选择一个单选按钮。 Each radio button has its' own value.
每个单选按钮都有自己的值。 Ex.
前任。 `"Good", "Fair", "Poor", "N/A".
`“好”、“一般”、“差”、“不适用”。
When a radio button is selected a state is generated dynamically for that section and question.选择单按钮时,state是为该部分和问题动态生成的。 Ex.
前任。
formAnswers({
kitchen: {
question: "Good"
question2: "Poor"
}
})
The goal here is the button that I want to create that checks only one value for each question Ex.这里的目标是我要创建的按钮,它只检查每个问题 Ex 的一个值。 clicks button
question: "Good", question2: "Good"
etc..点击按钮
question: "Good", question2: "Good"
等。
For me to set the state of a dynamic value I would need the "Section name" lets call it Name
and the "Question" we'll call it question
.对我来说,将 state 设置为动态值,我需要“Section name”让我们称之为
Name
和“Question”我们称之为question
。 That would give me access to the value like so formAnswers[Name][question]: value
这将使我能够像这样访问值
formAnswers[Name][question]: value
I am trying to set that state from a component called SectionHeader
.我正在尝试从名为 SectionHeader 的组件中设置
SectionHeader
。 These contain the buttons.这些包含按钮。
SectionHeader.js 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>
);
}
The parent of Section Header
and the rest of the form code excluding the child radio buttons which I have explained, are in another component LivingRoom.js
Section Header
的父级和表单代码的 rest不包括我已经解释的子单选按钮,位于另一个组件LivingRoom.js
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>
);
}
If there is anything I am missing please let me know, I would be happy to share it.如果有什么我想念的,请告诉我,我很乐意分享。 Cheers
干杯
Edit: for anyone that needs the radio buttons component.编辑:适用于需要单选按钮组件的任何人。
Ratings.js 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>
);
}
I do not completely understand your question, I am sorry but I think this will help you.我不完全理解你的问题,很抱歉,但我认为这会对你有所帮助。 Here is an implementation of radio buttons using react -
这是使用反应的单选按钮的实现 -
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>
);
}
}
After a few attempts, I was able to figure out the solution to this issue.经过几次尝试,我能够找出解决此问题的方法。
The key here was to figure out a way to get gather each question so that it may be used as a key when setting the state.这里的关键是想办法收集每个问题,以便在设置 state 时将其用作关键。 As my questions were stored in a ContextAPI, I was able to pull them out like so...
由于我的问题存储在 ContextAPI 中,因此我能够像这样将它们拉出来......
this may not be the best solution however it worked for me.这可能不是最好的解决方案,但它对我有用。
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" },
}));
});
};
I was able to map through each question since the name
is being passed through props is a key inside the actual object, formQuestions[name]
.我能够通过每个问题 map ,因为
name
正在通过道具是实际 object 中的一个键, formQuestions[name]
。 Because i'm mapping through each one I can set that question as a key and return the new state for each question to whatever I would like.因为我正在映射每个问题,所以我可以将该问题设置为一个键,并将每个问题的新 state 返回到我想要的任何问题。
However, if I was to create an onClick={setState('Good')}
, React didn't like that and it created an infinite loop.但是,如果我要创建一个
onClick={setState('Good')}
,React 不喜欢这样,它会创建一个无限循环。 I will look for more solutions and update this post if I find one.如果我找到一个,我会寻找更多的解决方案并更新这篇文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.