动态呈现表单的特定处理程序方法

specific handler method for dynamaically rendered form

我有 3 个渲染 n 次的 materialUI TextField(n 是用户在渲染表单字段之前输入的整数,这里我将它存储在一个名为 groupMembersCount 的变量中)。我在 ReactJS 中使用功能组件定义一个带有 useState 挂钩的数组:

const [groupDetails, setGroupDetails] = React.useState([
    { fullName: "", phoneNo: "", gender: "" },
  ]);

我正在通过这种方式动态渲染它:

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

我想在动态呈现的表单字段 (phoneNo) 上创建一个 onChange 处理程序来检查用户输入的内容,在该处理程序方法中我将添加两个道具 "error" 以使手机号码字段变为红色, 和 "helperText" 以显示消息(例如,如果用户在数字中键入字母,则数字不正确)。 现在,如果我正在检查数字字段的验证,错误和 helperText 将出现在所有手机号码输入字段中(在 n 次呈现的行中)。我希望它特定于用户输入的行。

希望我把问题陈述解释清楚了,如果没有,请询​​问任何信息。

这里有一个验证输入的示例,这些输入是动态生成的。

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 DynamicGroupMember2() {
    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"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <TextField
                                id={`phoneNo${i + 1}`}
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                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"
                                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>
    );
}