简体   繁体   English

React - 错误:重新渲染太多。 React 限制渲染次数以防止无限循环

[英]React - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

Been stuck on this error: Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.一直卡在这个错误上: Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. After debugging, I think I found the last culprit.经过调试,我想我找到了最后一个罪魁祸首。 It was to do with the next following components.这与接下来的组件有关。 However I don't know why they are causing render issues.但是我不知道为什么它们会导致渲染问题。

export default function GetUserBuckets()
{
    const ListLoading = LoadingComponent(UserBuckets);
    const [appState, setAppState] = useState({
        loading: true,
        posts: null,
    });


    useEffect(() => {
        if (!appState.loading) return;
    
        axiosInstance.get('all/buckets/').then((res) => {
            const allBuckets = res.data;
            setAppState({ loading: false, buckets: allBuckets });
        });
    }, []);

    
    return (
            <ListLoading isLoading={appState.loading} buckets={appState.buckets} />

    );
};

Here is the child: This is a loading component that basically shows a loading indicator, when the loading is done, then it displays the original Component这是孩子:这是一个加载组件,基本上显示一个加载指示器,当加载完成时,它会显示原始Component

export function LoadingComponent(Component) {
    return function LoadingComponent({ isLoading, ...props }) {
        if (!isLoading) return <Component {...props} />;
        return (
        <Container  style={{justifyContent:"center",display:"flex", padding:"5rem"}} className="loadingCircle">
            <CircularProgress />
        </Container>
        );
    };
}
export default LoadingComponent;

Here is the component it loads.这是它加载的组件。 I'm pretty sure the error is somewhere here.我很确定错误在这里的某个地方。 However I cant find it?但是我找不到它?

const UserBuckets = (props) => {
    const { buckets } = props;
    console.log(buckets[0].id)
    const [openDeletePopUp, setOpenDeletePopUp] = useState(false);
    const [bucketName, setBucketName] = useState('');
    const [openEditPopUp, setOpenEditPopUp] = useState(false);
    const [bucketId, setBucketId] = useState(null)
    const randomStocks = Math.floor(Math.random() * buckets.stock_count);

    const [anchorEl, setAnchorEl] = React.useState(null);

    const [currentIndex, setCurrentIndex] = useState(0);

    const theme = useTheme()

    const classes = useStyles();

    const handleClick = (index) => (event) => {
        setAnchorEl(event.currentTarget);
        setCurrentIndex(index);
      };
  
    const handleClickDeleteOpen = (bucket, id) => {
        setOpenDeletePopUp(true);
        setBucketName(bucket)
        setBucketId(id)
    };
    
    const handleClickEditOpen = () => {
        setOpenEditPopUp(true);
      };
      
  
      const handleClose = () => {
        setAnchorEl(null);
      };
    
      const handleDeleteClose = () => {
        setOpenDeletePopUp(false);
      };

    console.log(buckets && buckets)

    if (!buckets || buckets.length === 0) return <p>Can not find any buckets, make one below!</p>;
    return (
        <React.Fragment>
            <Container style={{width:"90%"}} maxWidth="md" component="main">
                <Grid container spacing={5} alignItems="stretch">
                    {buckets.map((bucket, index) =>
                    {
                    return (
                        <Grid item key={index} xs={12} sm={6} md={4} lg={4}>
                            <Card
                            className={classes.root}
                            style={{  height: "100%", borderRadius:"20px"}}
                            >
                            {(!bucket || bucket.stock_list === null) &&
                                <CardHeader className={classes.bucketTitle} classes={{ title: classes.bucketTitle }}
                                        title={
                                            <>
                                            <Link 
                                                color="textPrimary"
                                                href={'dash/' + bucket.slug}
                                                className={classes.link}
                                                style={{ textDecoration: 'none' }}
                                            >
                                            {bucket.name.substr(0, 50)}
                                            </Link>
                                            </>
                                        }
                                        subheader="Add Stocks to get started!"
                                        action={
                                            <>
                                            <IconButton 
                                                style={{padding:0, marginTop:10}}
                                                onClick={handleClick(index)}
                                                aria-label="settings">
                                                <MoreVertIcon />
                                            </IconButton>
                                                <Menu
                                                    id="simple-menu"
                                                    anchorEl={anchorEl}
                                                    keepMounted
                                                    open={Boolean(anchorEl) && index === currentIndex}
                                                    onClose={handleClose}
                                                    style={{boxShadow: 'none'}}
                                                    elevation={0}
                                                >
                                                    <MenuItem onClick={handleClickDeleteOpen}>Edit </MenuItem>
                                                    <MenuItem onClick={setOpenEditPopUp(true)}>Delete</MenuItem>
                                                </Menu>
                                            </>
                                        }
                            />}
                            {bucket && bucket.stock_list != null &&
                                <CardHeader className="cardHeaderBucket" 
                                    title={
                                        <>
                                        <Link 
                                            color="textPrimary"
                                            href={'dash/' + bucket.slug}
                                            className={classes.link}
                                            style={{ textDecoration: 'none', color: "white", margin:0 }}
                                        >
                                            {bucket.name.substr(0, 50)}
                                        </Link>
                                        </>}
                                    action={
                                        <>
                                            <IconButton
                                                style={{padding:0}}
                                             onClick={handleClick(index)}
                                            aria-label="settings">
                                                <MoreVertIcon />
                                            </IconButton>
                                            <Menu
                                                id="simple-menu"
                                                anchorEl={anchorEl}
                                                keepMounted
                                                open={Boolean(anchorEl) && index === currentIndex}
                                                onClose={handleClose}
                                            >
                                                <MenuItem onClick={function(event){ handleClickEditOpen(); handleClose()}}>Edit</MenuItem>
                                                <MenuItem onClick={function(event){ handleClickDeleteOpen(bucket.name, bucket.id); handleClose()}}>Delete </MenuItem>
                                            </Menu>
                                        </>
                                    }
                                    style={{margin:0, textIndent:0}}
                                />}
                                
                                <CardContent className="cardContentBucket">
                                    {(!bucket || bucket.bucket_pos_neg === null) &&
                                    <p style={{ textAlign: "center" }} >
                                        Your Bucket is empty...
                                    </p>}
                                    {bucket && bucket.bucket_pos_neg != null &&
                                    <div className={classes.bucketText}>
                                    <Grid container>
                                        <Grid item xs={12} style={{marginTop:10}}>  
                                            {bucket.bucket_sectors.slice(0, 3)
                                            .sort((a, b) => a.count > b.count)
                                                    .map((stock, index) =>
                                                    {return(
                                                        <Chip key={index} label={stock.sector} size="small" className="stockChips" />
                                                    )}
                                                )}
                                                <>
                                                    {(bucket.bucket_sectors.length > 3) &&
                                                    <Chip key={index} label={bucket.bucket_sectors.length - 3 +"+ more" } size="small" className="stockChips" />
                                                    }
                                                </>
                                
                                            </Grid>
                                        <Grid item>
                                        <Grid item xs={12} sm={12}> 
                                            <Typography variant="overline" color="textSecondary">
                                                {"Total Stocks: " + bucket.stock_count}
                                            </Typography>
                                        </Grid>
                                        <Typography variant="overline"  color="textSecondary">
                                            Return Donut                
                                        </Typography>
                                        </Grid>
                                        <BucketDoughnutDisplay data={bucket.bucket_pos_neg} />
                                        </Grid>
                                    </div>
                                            }   
                                </CardContent>                              
                            </Card>
                        </Grid>                 
                        );                              
                    })}
                </Grid>
            </Container>
            <DeleteBucketPopUp open={openDeletePopUp} handleClose={handleDeleteClose} bucket={bucketName} id={bucketId}/>
        </React.Fragment>
    );
};

Is there something out of the ordinary in any of the components above that would cause infinite loop of redners?上面的任何组件中是否有一些不寻常的东西会导致红人无限循环?

From what I can infer:-据我所知:-

<MenuItem onClick={setOpenEditPopUp(true)}>Delete</MenuItem>

should be应该

<MenuItem onClick={handleClickEditOpen}>Delete</MenuItem>

Explanation: On each render there is invocation of setOpenEditPopUp(true) rather than binding it as event handler as you expected it to be.说明:在每次渲染时都会调用setOpenEditPopUp(true) ,而不是像您预期的那样将其绑定为事件处理程序。 Since you already have handleClickEditOpen declared, reusing it here would make sense.由于您已经声明了handleClickEditOpen ,因此在这里重用它是有意义的。

The error is probably in the following part of your code:错误可能在代码的以下部分:

 <IconButton 
      style={{padding:0, marginTop:10}}
      onClick={handleClick(index)}
      aria-label="settings">
  <MoreVertIcon />
</IconButton>

Your onClick function is constantly being executed, and that is what´s the causing the re-renders.您的 onClick function 一直在执行,这就是导致重新渲染的原因。 Instead you need to pass it as a callback, so it will only execute when the user click on the button:相反,您需要将它作为回调传递,因此它只会在用户单击按钮时执行:

  <IconButton 
          style={{padding:0, marginTop:10}}
          onClick={(index) => handleClick(index)}
          aria-label="settings">
      <MoreVertIcon />
    </IconButton>

There are other parts of the code in which the function is being called constantly, like here:代码的其他部分会不断调用 function,如下所示:

 <MenuItem onClick={setOpenEditPopUp(true)}>Delete</MenuItem>

So remeber to replace them with callbacks.所以请记住用回调替换它们。

暂无
暂无

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

相关问题 错误:重新渲染过多。 React 限制渲染次数以防止无限循环。 反应 - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. React 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 - 反应 - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. - React React-Error:重新渲染太多。 React 限制渲染次数以防止无限循环 - React-Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 - 反应 JS - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. - React JS 反应错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - React Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 反应:错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - React: Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 服务器错误错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - Server Error Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 错误太多重新渲染。 react 限制渲染次数以防止无限循环 - error too many re-renders. react limits the number of renders to prevent an infinite loop "<i>Uncaught Error: Too many re-renders.<\/i>未捕获的错误:重新渲染过多。<\/b> <i>React limits the number of renders to prevent an infinite loop - ProtectedRoutes Component<\/i> React 限制渲染次数以防止无限循环 - ProtectedRoutes 组件<\/b>" - Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop - ProtectedRoutes Component 我有一个错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - I have an error: Too many re-renders. React limits the number of renders to prevent an infinite loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM