специальный метод обработчика для динамически отображаемой формы

У меня есть 3 textFields materialUI, которые визуализируются n раз (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>
    );
}

Я хочу создать один обработчик onChange для динамически отображаемого поля формы (phoneNo), чтобы проверить, что набирает пользователь, и в этом методе обработчика я добавлю два реквизита «ошибка», чтобы сделать поле мобильного номера красным, и «helperText» для отображения сообщение (например, неправильный номер, если пользователь вводит алфавит в номер). теперь, если я проверяю проверку поля номера, ошибка и helperText появляются во всех полях ввода номера мобильного телефона (в n раз отображаемых строках). Я хочу, чтобы он был специфичен для строки, в которую входит пользователь.

Надеюсь, я хорошо объяснил постановку задачи, если нет, пожалуйста, запросите любую информацию.


person kushal verma    schedule 30.05.2020    source источник


Ответы (1)


вот пример для проверки входных данных, которые генерируются динамически.

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>
    );
}
person Khabir    schedule 30.05.2020
comment
Большое спасибо, это действительно сработало. большое спасибо - person kushal verma; 31.05.2020
comment
У меня есть еще одно сомнение, что мы динамически создаем эти поля формы, что, если я заполнил число (groupMembersCount), а затем заполнил эти поля формы, и после заполнения я изменил groupMembersCount (увеличив или уменьшив), в случае увеличения я хочу, чтобы значения, заполненные пользователем, должны сохраняться, а при уменьшении значения полей формы должны очищаться. Должен ли я опубликовать это как еще один вопрос? - person kushal verma; 31.05.2020
comment
Я попытался передать значения из массива groupDetails для формирования в свойстве значения, но он показывает ошибку, потому что индекс, который я записываю/передаю значения, изначально не существует в этом индексе. - person kushal verma; 31.05.2020
comment
Да, пожалуйста, создайте новый вопрос - person Khabir; 31.05.2020
comment
пожалуйста, найдите его здесь, stackoverflow. ком/вопросы/62121702/ - person kushal verma; 31.05.2020