简体   繁体   English

oksetState 函数未在反应挂钩中更新

[英]oksetState functions is not updated in react hooks

I am rendering the multiple forms upon the selection of no of users done through a dropdown button, where I am generating helper text and userdata state for those generated users dynamically.通过下拉按钮选择没有用户后,我正在渲染多个 forms,我正在为这些生成的用户动态生成帮助文本和用户数据 state。

this is where I initialize the state objects这是我初始化 state 对象的地方

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

THis is the handling of the drop-down button:这是下拉按钮的处理:

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

And this is the where the states are generated dynamically using the useEffect:这是使用 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])

This is where I render cards:这是我渲染卡片的地方:

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}
                            />
.....
.....

This is where the dropdown button is handled:这是处理下拉按钮的地方:

 <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>

I also have form validation which I call when the user clicks on the register button, to perform the checks on fields and now only the selectedIndex card fields are setting the error text previous remaining cards are not set with the error text.我也有表单验证,当用户单击注册按钮时,我会调用它来执行字段检查,现在只有 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" }}))
                }
            }
....

You must update your state only once and not within a for loop specially without using a state updater callback.您必须只更新一次 state 并且不能在 for 循环中特别不使用 state 更新程序回调。

You can perform the update by returning the object values within each state updater by mapping over an array created of length equal to selectedIndex您可以通过在每个 state 更新程序中返回 object 值来执行更新

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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM