Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在react钩子中未更新oksetState函数_Javascript_Reactjs_Asynchronous_React Hooks - Fatal编程技术网

Javascript 在react钩子中未更新oksetState函数

Javascript 在react钩子中未更新oksetState函数,javascript,reactjs,asynchronous,react-hooks,Javascript,Reactjs,Asynchronous,React Hooks,我通过一个下拉按钮选择了多少个用户,然后呈现多个表单, 在这里,我动态地为那些生成的用户生成助手文本和用户数据状态 这就是我初始化状态对象的地方 const [selectedIndex, setSelectedIndex] = React.useState(0); const [registrationData,setRegistrationData]=React.useState([]); const [error,setError]=React.useState({}); const [r

我通过一个下拉按钮选择了多少个用户,然后呈现多个表单, 在这里,我动态地为那些生成的用户生成助手文本和用户数据状态

这就是我初始化状态对象的地方

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}
                            />
.....
.....
registrations.filter((索引)=>{
返回(索引){
返回(
{index+1}
updateUserdata(事件、索引)}
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>
handleClick(事件)}
>
//在这里,我提到了selectedIndex+1只显示1而不是0
{selectedIndex+1}
{[1,2,3,4,5,6,7,8,9,10].map((选项,索引)=>(
handleMenuItemClick(事件、索引)}
>
{option}
))}
我还有表单验证,当用户单击register(注册)按钮时,我会调用表单验证,以对字段执行检查,现在只有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" }}))
                }
            }
....
const formValidation=()=>{
console.log(“输入表单验证函数”)
让valid=true;
对于(var i=0;i({…错误[i]:{…错误[i],id:“必需的”}}))
有效=错误
}否则{
if(!(registrationData[i].id).match(/^[0-9]+$/)| |([registrationData[i].id].length!==10)){
setError((error)=>({…error[i]:{…error[i],id:“required”}))
有效=错误
}否则{
setError((error)=>({…error[i]:{…error[i],id:“required”}))
}
}
....

您必须只更新一次状态,而不是在for循环中,特别是在不使用状态更新程序回调的情况下

通过映射长度等于selectedIndex的数组,可以在每个状态更新程序中返回对象值,从而执行更新

useffect(()=>{
setCampaign(prevCampaign=>({
…在竞选中,
…Object.assign({},…[…新数组(10).keys()].map(i=>({
[i] :{
sms_活动:错误,
电子邮件地址:false,
}
})))
}));
setError(prevError=>({
…错误,
…Object.assign({},…[…新数组(10).keys()].map(i=>({
[i] :{
id:“”,
名字:“,
中间名称:“”,
姓氏:“,
城市:“,
州:“,
国家:“,
电话号码:“,
电子邮件地址:“,
}
})))
}));
setRegistrationData(prevReg=>({
…prevReg,
…Object.assign({},…[…新数组(10).keys()].map(i=>({
[i] :{
id:“”,
名字:“,
中间名称:“”,
姓氏:“,
第节:“,
城市:“,
州:“,
国家:“,
电话号码:“,
电话号码:“,
电子邮件地址:“,
短信:“,
电子邮件:“
}
})))
}));
},[selectedIndex])

是的,您可以使用多个setState函数。但是设置状态后状态未更新。为什么您认为设置状态后状态未更新。您的证据是什么?请使用演示问题的示例更新您的问题,最好是使用堆栈片段运行的问题(《代码》[]工具栏按钮).Stack Snippets支持React,包括JSX;。此外,循环从
0开始,一直到
我已经更新了code请参考并说我的错误,请在使用setState进行循环更新时,状态值会被上次更新覆盖,这就是为什么您应该对状态更新程序使用回调方法。您的代码也会工作k如果你使用回调方法,但是设置一次状态是一种更好的方法好的,我会尝试请保持在线这对我来说是一项重要的工作你的回答解决了我的问题,但是你的useEffect方法生成10个对象,但是我希望关于selectedIndex和我的错误文本只为sele显示反恐执行局索引卡,而不是剩余的卡,我已经更新了问题,请检查在这种情况下,你不需要地图或循环。删除该部分,它应该像你想要的那样工作