Функции oksetState не обновляются в перехватчиках реакции - PullRequest
0 голосов
/ 30 мая 2020

Я визуализирую несколько форм после выбора ни одного из пользователей с помощью раскрывающейся кнопки, где я динамически генерирую вспомогательный текст и состояние пользовательских данных для этих сгенерированных пользователей.

здесь я инициализирую состояние объекты

const [selectedIndex, setSelectedIndex] = React.useState(0);
const [registrationData,setRegistrationData]=React.useState([]);
const [error,setError]=React.useState({});
const [registrations]=React.useState([]);
const [campaign, setCampaign] = React.useState({});

Это обработка раскрывающейся кнопки:

const handleMenuItemClick=(event, index)=>{
        console.log("CLicked "+(index+1))
        setSelectedIndex(index);
        setAnchorEl(null); 
};

И здесь состояния генерируются динамически с использованием useEffect:

 useEffect(()=>{
        setCampaign(prevCampaign => ({
            ...prevCampaign,
            ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
                [i]: {
                    sms_campaign: false,
                    email_campaign: false,
                }
            })))
        }));
        setError(prevError => ({
            ...prevError,
            ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
                [i]: {
                   uscf_id:"",
                   first_name:"",
                   middle_name:"",
                   last_name:"",
                   city:"",
                   state:"",
                   country:"",
                   phone_number:"",
                   email_id:"",
                }
            })))
        }));
        setRegistrationData(prevReg => ({
            ...prevReg,
            ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
                [i]: {
                uscf_id:"",
                first_name:"",
                middle_name:"",
                last_name:"",
                sections:"",
                city:"",
                state:"",
                country:"",
                phone_code:"",
                phone_number:"",
                email_id:"",
                sms:"",
                email:""
            }
            })))
        }));
        },[selectedIndex])

Здесь я визуализирую карточки:

registrations.filter((index)=>{
                    return (index<selectedIndex);
                }).map((registration,index)=>{
                    return(
                        <Card className={classes.cardLayout}>
                            <Avatar className={classes.icon}>
                                {index+1}
                            </Avatar>
                            <CardContent className={classes.cardContent}>
                            <TextField

                                id="outlined-error-helper-text"
                                label="ID"
                                name="id"
                                placeholder="Enter ID"
                                variant="outlined"
                                helperText={error[index].id}
                                error={(error[index].id===null||error[index].d==="")?false:true}
                                onChange={(event)=>updateUserdata(event,index)}
                                className={classes.textField}
                            />
.....
.....

Здесь обрабатывается раскрывающаяся кнопка:

 <Button
                    aria-controls="simple-menu" 
                    aria-haspopup="true" 
                    variant="outlined" 
                    color="inherit"  
                    label="registrations"
                    style={{marginLeft:20}}
                    endIcon={<ArrowDropDownIcon/>}
                    onClick={(event)=>handleClick(event)}
                    >
                    <Typography variant="body2" color="inherit">
                    //here , I have mentioned selectedIndex+1 to just show 1 instead of 0
                        {selectedIndex+1}
                    </Typography>
                    </Button>
                        <Menu
                            id="simple-menu"
                            anchorEl={anchorEl}
                            keepMounted    
                            open={Boolean(anchorEl)}
                            onClose={handleClose}
                        >
                        {[1,2,3,4,5,6,7,8,9,10].map((option, index) => (
                            <MenuItem                                       
                                style={{paddingRight:85}}
                                key={option}
                                name="no_of_registrations"
                                selected={(index === selectedIndex)}
                                onClick={(event) => handleMenuItemClick(event, index)}
                            >
                                {option}
                            </MenuItem>
                            ))}
                        </Menu>

У меня также есть проверка формы, которую я вызываю, когда пользователь нажимает на кнопку регистрации, чтобы выполнить проверки полей, и теперь только поля карты selectedIndex устанавливают текст ошибки, предыдущие оставшиеся карты не содержат текст ошибки.

const formValidation=()=>{
        console.log("entered Form validation function")
        let valid=true;
        for(var i=0;i<selectedIndex;i++){
            if(registrationData[i].id===""){
                setError((error)=>({...error,[i]:{...error[i],id:"required" }}))
                valid=false
            }else {
                if(!(registrationData[i].id).match(/^[0-9]+$/)||([registrationData[i].id].length!==10)){
                    setError((error)=>({...error,[i]:{...error[i],id:"required" }}))
                    valid=false
                }else{
                    setError((error)=>({...error,[i]:{...error[i],id:"required" }}))
                }
            }
....

1 Ответ

1 голос
/ 30 мая 2020

Вы должны обновить свое состояние только один раз, а не в пределах l oop, особенно без использования обратного вызова средства обновления состояния.

Вы можете выполнить обновление, возвращая значения объекта в каждом средстве обновления состояния путем сопоставления созданный массив длины, равной selectedIndex

useEffect(()=>{
    setCampaign(prevCampaign => ({
        ...prevCampaign,
        ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
            [i]: {
                sms_campaign: false,
                email_campaign: false,
            }
        })))
    }));
    setError(prevError => ({
        ...prevError,
        ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
            [i]: {
               id:"",
               first_name:"",
               middle_name:"",
               last_name:"",
               city:"",
               state:"",
               country:"",
               phone_number:"",
               email_id:"",
            }
        })))
    }));
    setRegistrationData(prevReg => ({
        ...prevReg,
        ...Object.assign({}, ...[...new Array(10).keys()].map(i => ({
            [i]: {
            id:"",
            first_name:"",
            middle_name:"",
            last_name:"",
            sections:"",
            city:"",
            state:"",
            country:"",
            phone_code:"",
            phone_number:"",
            email_id:"",
            sms:"",
            email:""
        }
        })))
    }));
    },[selectedIndex])
...