簡體   English   中英

在一個組件中使用多個單選按鈕組更新 state

[英]Updating state with multiple radio button groups in one component react

我正在嘗試使用單選按鈕的值更新我的組件的 state。 當我進行第二個單選按鈕選擇(狀態原因)時,我收到一條錯誤消息告訴我

Uncaught TypeError: cannot read properties of undefined (reading 'map')

當我單擊提交按鈕時,state 僅顯示第一組單選按鈕的 state 即當前狀態,然后將所選值顯示為空字符串(默認 Z9ED39E2EA931586B6A985A6942EF57 的值而不是按鈕值)選擇

任何人都可以幫忙嗎? 這是我的代碼:

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;

handleChange中,以下不是有效的 state 更新。 因此,您的 state 在每次單擊單選按鈕后都缺少options條目。

setQuestionState(...options, {nextState});

第一種方式

上述行應替換為以下行。

setQuestionState({ ...questionState, options: nextState });

編輯適度-ramanujan-mj25i

第二種方式

使用更新 state 的回調版本始終是安全的。 因此, handleChange function 應如下更正。

  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 };
          }
        })
      };
    });
  };

編輯胡思亂想的cohen-cjseb

暫無
暫無

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

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