在反应中填充动态呈现的表单字段

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在反应中填充动态呈现的表单字段相关的知识,希望对你有一定的参考价值。

我有3个materialUI TextField,它们被渲染了n次(n是渲染表单字段之前用户的整数输入,我将其存储在名为groupMembersCount的变量中)。我通过这种方式动态渲染它:

export default function DynamicGroupMember() 
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        fullName: "", phoneNo: "", gender: "",
    ]);
  function handleChange(event, index) 
        console.log(event.target.value, index);
        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = ...item, [event.target.name]: event.target.value;
        newArr[index] = item;

        setGroupDetails(newArr);
    

    return (
        <div>
            Number of Group: <TextField name="groupMembersCount" onChange=(event) => 
            setGroupMembersCount(event.target.value)
        />
            Array.apply(null, length: groupMembersCount).map(
                (e, i) => (
                    <div key=i>
                        <strong>Member #i + 1</strong>
                        <div className="getIndex" name=i + 1>
                            <TextField
                                id=`name$i + 1`
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                            />
                            <TextField
                                id=`phoneNo$i + 1`
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                            />
                            <Select
                                id=`gender$i + 1`
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>
                        </div>
                    </div>
                )
            )
            <Button onClick=() => 
                setShow(true)
            >Show</Button>
            
                show ?
                    groupDetails.map(member =>
                        <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                member.fullName
                            </Typography>
                            <Typography variant="h5" component="h2">
                                member.phoneNo
                            </Typography>
                            <Typography color="textSecondary">
                                member.gender
                            </Typography>
                        </CardContent>
                    </Card>) : null
            
        </div>
    );

如果我填写数字(groupMembersCount),然后填写那些表单字段,然后填写,我修改了groupMembersCount增加或减少),如果要增加,该怎么办?用户填写的值应保留,如果减少,则表单字段值应清除。我尝试从groupDetails数组传递值以在“值”属性中形成表单,但它显示错误,因为最初写/传递值的索引在该索引处不存在。

答案

您需要使用groupDetails之前存储的useState中的设置值。请检查以下示例:

import TextField from "@material-ui/core/TextField";
import React, useState from "react";
import Select from "@material-ui/core/Select";
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography";

export default function DynamicGroupMember3() 
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [errorText, setErrorText] = useState([]);
    const [showState, setShowState] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        fullName: "", phoneNo: "", gender: "",
    ]);
    const [state, setState] = React.useState(
        idProof: "",
        noOfPeople: "",
        bookingId: "",
        detailsOfPeople: [],
    );

    function handleChange(event, index) 
        event.preventDefault();
        console.log(errorText.length, 'length');
        if (event.target.name === "phoneNo") 
            // do validation here
            let valid = false;
            if (isNaN(event.target.value)) 
                let arr = [...errorText];
                arr[index] = 'Invalid ' + event.target.name;
                setErrorText(arr);
            
            else 
                let arr = [...errorText];
                arr[index] = '';
                setErrorText(arr);
            
        

        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = ...item, [event.target.name]: event.target.value;
        newArr[index] = item;
        setGroupDetails(newArr);
    

    return (
        <div>
            Number of Group: <TextField name="groupMembersCount" onChange=(event) => 
                if(isNaN(event.target.value))
                    alert('Please enter number');
                    return;
                
                if(event.target.value !== '') 
                    let errors = new Array(parseInt(event.target.value));
                    setErrorText(errors);
                    setGroupMembersCount(event.target.value);
                    console.log(errorText[1], 'errorText[i]')
                
        />
            Array.apply(null, length: groupMembersCount).map(

                (e, i) => (
                    <div key=i>
                        <strong>Member #i + 1</strong>
                        <div className="getIndex" name=i + 1>
                            <TextField
                                id=`name$i + 1`
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                value=groupDetails[i]? groupDetails[i].fullName: ''
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                            />
                            <TextField
                                id=`phoneNo$i + 1`
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                value=groupDetails[i]? groupDetails[i].phoneNo: ''
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                                error=errorText[i] !== '' && errorText[i] !== undefined
                                helperText=errorText[i]
                            />
                            <Select
                                id=`gender$i + 1`
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                value=groupDetails[i]? groupDetails[i].gender: ''
                                onChange=(event) => 
                                    handleChange(event, i)
                                
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>
                        </div>
                    </div>
                )
            )
            <Button onClick=() => 
                setShow(true)
            >Show</Button>
            
                show ?
                    groupDetails.map((member, index) =>
                        <Card key=index>
                            <CardContent>
                                <Typography color="textSecondary" gutterBottom>
                                    member.fullName
                                </Typography>
                                <Typography variant="h5" component="h2">
                                    member.phoneNo
                                </Typography>
                                <Typography color="textSecondary">
                                    member.gender
                                </Typography>
                            </CardContent>
                        </Card>) : null
            
            <Button onClick=() => 
                console.log(groupDetails, 'groupDetails');
                setState(
                    idProof: "XYZ123",
                    noOfPeople: groupDetails.length,
                    bookingId: "boking-4434",
                    detailsOfPeople: groupDetails
                );
                console.log(groupDetails, 'groupDetails');
                setShowState(true);

            >Show STATE</Button>
            
                showState ?
                    <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                Id Proof: state.idProof
                            </Typography>
                            <Typography variant="h5" component="h2">
                                No Of People: state.noOfPeople
                            </Typography>
                            <Typography color="textSecondary">
                                Booking Id: state.bookingId
                            </Typography>
                        </CardContent>
                    </Card> : null
            
        </div>
    );

以上是关于在反应中填充动态呈现的表单字段的主要内容,如果未能解决你的问题,请参考以下文章

动态表单 - 如何使用反应钩子更新“onChange”事件中多个表单字段的值?

angular 7 反应式表单:为表单中的每个输入字段动态添加/删除输入字段

如何在标签中使用表格控件名称-角反应形式

R闪亮:填写提示用户并支持自动填充功能的表单时不需要的反应

如何在反应中验证多步表单

禁用反应形式的输入字段