我试图用单选按钮的值更新组件的状态。当我选择第二个单选按钮(状态的原因)时,我得到一个错误告诉我
Uncaught TypeError: cannot read properties of undefined (reading 'map')单击submit按钮时,状态仅显示第一组单选按钮的状态(即当前状态),然后将所选值显示为空字符串(默认状态值),而不是按单选按钮选择的值。
有人能帮忙吗?这是我的代码:
import {Container, Row, Col, Form, Button } from 'react-bootstrap';
import { useState } from 'react';
const Question = (q) => {
//state to hold responses from input
const [questionState, setQuestionState] = useState({
options: [
{ radioName: 'currentstatus',
selected: '' },
{ radioName: 'reasonstatus',
selected: ''},
{ radioName: 'actions',
selected: ''},
{ radioName: 'actowner',
selected: ''},
{ radioName: 'actstat',
selected: ''}
]
});
//EVENT HANDLERS
//radio buttons onchange
const handleChange = (e)=>{
const { options } = questionState;
const {name, value} = e.target;
console.log(name, value);
const nextState = options.map( opt => {
if (opt.radioName !== name) {
return {...opt}
} else {
return {...opt,
selected: value}
}
});
setQuestionState(...options, {nextState});
}
//date picker event
const handleDate = (e) => {
console.log(e.target.value);
}
//overall form submission
const handleSubmit = (e) => {
console.log(questionState);
}
const question = q;
return(
<Container>
<div className="question mb-5">
<Form className="border border-3 border-primary p-3 m-2">
<Form.Group className="mb-2">
<Row className="bg-primary text-white p-2">
<div className="fs-5">{question.question}</div>
</Row>
{/* ---------------- CURRENT STATUS ----------------------- */}
<Form.Label className="fs-4 fw-bold">Current Status:</Form.Label>
<div key="currStat" className="mb-3">
<Form.Check inline label="Fully meeting expectation" name="currentstatus" type="radio" id='status-1' value="1" onChange={handleChange}/>
<Form.Check inline label="Partially meeting expectation" name="currentstatus" type="radio" id='status-2' value="2" onChange={handleChange}/>
<Form.Check inline label="Not meeting expectation" name="currentstatus" type="radio" id='status-3' value="3" onChange={handleChange}/>
<Form.Check inline label="Not applicable" name="currentstatus" type="radio" id='status-4' value="4" onChange={handleChange}/>
</div>
{/* -------------------- REASONS FOR STATUS --------------------------- */}
<Form.Label className="fs-4 fw-bold">Reason for Status:</Form.Label>
<div key="reasStat" className="mb-3">
<Form.Check inline label="Reason 1" name="reasonstatus" type="radio" id='reason-1' value="1" onChange={handleChange}/>
<Form.Check inline label="Reason 2" name="reasonstatus" type="radio" id='reason-2' value="2" onChange={handleChange}/>
<Form.Check inline label="Reason 3" name="reasonstatus" type="radio" id='reason-3' value="3" onChange={handleChange}/>
<Form.Check inline label="Reason 4" name="reasonstatus" type="radio" id='reason-4' value="4" onChange={handleChange}/>
</div>
{/* -------------------- ACTIONS --------------------------- */}
<Form.Label className="fs-4 fw-bold">Action to be taken:</Form.Label>
<div key="actions" className="mb-3">
<Form.Check inline label="Action 1" name="actions" type="radio" id='act-1' value="1" onChange={handleChange}/>
<Form.Check inline label="Action 2" name="actions" type="radio" id='act-2' value="2" onChange={handleChange}/>
<Form.Check inline label="Action 3" name="actions" type="radio" id='act-3' value="3" onChange={handleChange}/>
<Form.Check inline label="Action 4" name="actions" type="radio" id='act-4' value="4" onChange={handleChange}/>
</div>
{/* -------------------- ACTION OWNER --------------------------- */}
<Form.Label className="fs-4 fw-bold">Action Owner:</Form.Label>
<div key="actOwner" className="mb-3">
<Form.Check inline label="User 1" name="actowner" type="radio" id='user-1' value="1" onChange={handleChange}/>
<Form.Check inline label="User 2" name="actowner" type="radio" id='user-2' value="2" onChange={handleChange}/>
</div>
{/* -------------------- ACTION STATUS --------------------------- */}
<Form.Label className="fs-4 fw-bold">Action Status:</Form.Label>
<div key="actStat" className="mb-3">
<Form.Check inline label="Not started" name="actstat" type="radio"id='actStat-1' value="1" onChange={handleChange}/>
<Form.Check inline label="In progress" name="actstat" type="radio" id='actStat-2' value="2" onChange={handleChange}/>
<Form.Check inline label="Completed" name="actstat" type="radio" id='actStat-3' value="3" onChange={handleChange}/>
</div>
{/* --------------------- DATE PICKER ------------------------- */}
<Row>
<Col xs={4}>
<Form.Label className="fs-4 fw-bold">Due Date:</Form.Label>
<Form.Control xs={4} type="date" className="mb-3" onChange={handleDate}/>
</Col>
</Row>
<Row className="justify-content-end">
<Col xs={2}>
<Button onClick = {handleSubmit}>Submit</Button>
</Col>
</Row>
</Form.Group>
</Form>
</div>
</Container>
)
}
export default Question;发布于 2022-02-04 16:09:42
在handleChange中,以下不是有效的状态更新。因此,在单击每个单选按钮后,您的状态都缺少options条目。
setQuestionState(...options, {nextState});第一条路
以上一行应改为以下内容。
setQuestionState({ ...questionState, options: nextState });
第二条路
使用更新状态的回调版本总是安全的。因此,handleChange函数应按以下方式进行更正。
const handleChange = (e) => {
const { name, value } = e.target;
setQuestionState((prevState) => {
return {
...prevState,
options: prevState.options.map((opt) => {
if (opt.radioName !== name) {
return { ...opt };
} else {
return { ...opt, selected: value };
}
})
};
});
};
https://stackoverflow.com/questions/70989402
复制相似问题