【问题标题】:Too many re-renders. React limits the number of renders to prevent an infinite loop material太多的重新渲染。 React 限制渲染次数以防止无限循环素材
【发布时间】:2019-12-28 13:11:45
【问题描述】:
import React, { useState } from "react";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import Link from "@material-ui/core/Link";
import Grid from "@material-ui/core/Grid";
import Box from "@material-ui/core/Box";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";

function Copyright() {
  return (
    <Typography variant="body2" color="textSecondary" align="center">
      {"Copyright © "}
      <Link color="inherit" href="https://material-ui.com/">
        Archents
      </Link>{" "}
      {new Date().getFullYear()}
      {"."}
    </Typography>
  );
}

const useStyles = makeStyles(theme => ({
  paper: {
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main
  },
  form: {
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(3)
  },
  submit: {
    margin: theme.spacing(3, 0, 2)
  }
}));

const SignUp = () => {
  const classes = useStyles();
  const [userProfile, setProfile] = useState({
    firstName: "",
    lastName: "",
    email: "",
    phone: "",
    organization: "",
    title: "",
    password: "",
    role: ""
  });

  const {
    firstName,
    lastName,
    email,
    phone,
    org,
    title,
    password,
    role
  } = userProfile;

  const handleChange = async event => {
    event.preventDefault();
    const { name, value } = event.target;

    setProfile({
      ...userProfile,
      [name]: value
    });
  };

  const onSubmitSignUp = () => {
    console.log(setProfile);
  };

  return (
    <Container component="main" maxWidth="xs">
      <CssBaseline />
      <div className={classes.paper}>
        <Avatar className={classes.avatar}>
          <LockOutlinedIcon />
        </Avatar>
        <Typography component="h1" variant="h5">
          Sign up
        </Typography>
        <form className={classes.form} noValidate>
          <Grid container spacing={2}>
            <Grid item xs={12} sm={6}>
              <TextField
                autoComplete="fname"
                name="firstName"
                variant="outlined"
                required
                fullWidth
                id="firstName"
                label="First Name"
                autoFocus
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                id="lastName"
                label="Last Name"
                name="lastName"
                autoComplete="lname"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                id="email"
                label="Email"
                name="email"
                autoComplete="email"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                type="tel"
                id="phone"
                label="Phone"
                name="phone"
                autoComplete="phone"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                id="organization"
                label="Organization"
                name="organization"
                autoComplete="organization"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                id="title"
                label="Title"
                name="title"
                autoComplete="title"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                name="password"
                label="Password"
                type="password"
                id="password"
                autoComplete="current-password"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12} sm={6}>
              <TextField
                variant="outlined"
                required
                fullWidth
                name="confirm-password"
                label="Confirm Password"
                type="password"
                id="confirm-password"
                autoComplete="confirm-password"
              />
            </Grid>
            <Grid item xs={12}>
              <TextField
                variant="outlined"
                required
                fullWidth
                name="role"
                label="Role"
                id="role"
                autoComplete="role"
                onChange={handleChange}
              />
            </Grid>
            <Grid item xs={12}>
              <FormControlLabel
                control={<Checkbox value="allowExtraEmails" color="primary" />}
                label="Remember me"
              />
            </Grid>
          </Grid>
          <Button
            fullWidth
            variant="contained"
            color="primary"
            className={classes.submit}
            onClick={onSubmitSignUp}
          >
            Sign Up
          </Button>
          <Grid container justify="flex-end">
            <Grid item>
              <Link href="#" variant="body2">
                Already have an account? Sign in
              </Link>
            </Grid>
          </Grid>
        </form>
      </div>
      <Box mt={5}>
        <Copyright />
      </Box>
    </Container>
  );
};

export default SignUp;

这是来自 Material UI 的模板。我从 GitHub 上的 Sign Up 中选择了这个模板,我只导入了 useState 并尝试使用它。

它抛出“重新渲染太多。React 限制渲染数量以防止无限循环材质”,

我尝试过使用 react 钩子,因为我无法实现类。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    我不明白你为什么这样做:

    const [use, set] = useState("nothing");
    set("something");
    

    这会导致应用无限重新渲染。每次调用 set 时,它都会重新渲染。通常你会在某个钩子中调用它,条件如下:

    useEffect(() => {
      set('something');
    }, []);
    

    这只会在组件安装时调用set,而不是连续调用。换句话说,不要在钩子之外使用 setter 函数。最常见的使用 setter 函数的钩子是 useCallback 和 useEffect。

    请参阅documentation 了解更多信息。

    您应该使用useCallback 挂钩来设置状态。也没有理由让它async。

    const handleChange = useCallback(event => {
      event.preventDefault();
      const { name, value } = event.target;
    
      setProfile({
        ...userProfile,
        [name]: value
      });
    }, [userProfile]);
    

    【讨论】:

    • 我更新了答案。让我知道这是否有效。不要忘记导入useCallback。
    猜你喜欢
    • 2020-09-22
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 2021-07-01
    • 2021-05-17
    相关资源
    最近更新 更多