状态更改不会影响React DOM

时间:2020-08-20 17:28:07

标签: reactjs material-ui react-material

我正在使用React Material UI。为了加载,我决定使用Skeleton结构。但是,状态更改不会影响骨架组件的宽度和高度,因此无法正常工作。

export default function ComplexGrid(props) {
  const [hover, setHover] = useState(false);
  const [article, setArticle] = useState("");
  const [year, setYear] = useState("");
  const [month, setMonth] = useState("");
  const [loaded, setLoaded] = useState(false);

  const [width, setWidth] = useState(null);
  const [height, setHeight] = useState(null);

  const skeletonStructure = useRef(null);

  const classes = useStyles();

  useEffect(() => {
    if (props.mainNew[0]) {
      setArticle(props.mainNew[0]);
      setYear(String(article.updated_at).split("-")[0]);
      setMonth(String(article.updated_at).split("-")[1]);
    }

    if (skeletonStructure.current) {
      setWidth(skeletonStructure.current.offsetWidth);
      setHeight(skeletonStructure.current.offsetHeight);
    }

    setTimeout(() => {
      setLoaded(true);
    }, 500);
  });

  const stylehvr = loaded && hover && article ? { cursor: "pointer", opacity: "60%", transition: "all 0.5s linear" } : {};
  const hoverbck = loaded && hover && article ? { backgroundColor: "black", cursor: "pointer" } : {};

  return (
    <div className={classes.root} onMouseOver={() => setHover(true)} onMouseOut={() => setHover(false)}>
      <Grid container spacing={2} className={classes.grd}>
        <div style={hoverbck}>
          {article && loaded ? (
            <img ref={skeletonStructure} className={classes.img} style={stylehvr} alt={article.title} src={article.img1} />
          ) : (
            <Skeleton variant="rect" width={width} height={height} animation="pulse" />
          )}

          {article && loaded ? (
            <Typography gutterBottom variant="subtitle1" className={classes.title}>
              {article.title} - {width} - {height}
            </Typography>
          ) : (
            ""
          )}

          {article && loaded ? (
            <Typography variant="body2" color="textSecondary" className={classes.date}>
              {month} / {year}
            </Typography>
          ) : (
            ""
          )}

          {article && loaded ? (
            <Typography variant="body2" color="textSecondary" className={classes.timer}>
              {article.read_time} Dakikalık Okuma
            </Typography>
          ) : (
            ""
          )}

          {article && loaded ? (
            <Typography variant="body2" className={classes.type}>
              {article.content_type}
            </Typography>
          ) : (
            ""
          )}
        </div>
      </Grid>
    </div>
  );
}

由于身高和体重的初始状态为“空”,因此骨架无法按预期工作,但是在useEffect中正确设置了身高和体重。如何为骨架组件使用正确的状态?

2 个答案:

答案 0 :(得分:0)

尝试在useEffect挂钩中将所有状态设置为依赖项

useEffect(() => {//your code}, [//all states here])

答案 1 :(得分:0)

要赋予对UseEffect的依赖性,您需要这样赋予它。

useEffect(() => {
  //your code which should be executed when dependent state updates.
}, [state names])

//UPDATED 
useEffect(() => {
 if(props.mainNew[0]){
    setArticle(props.mainNew[0])
    setYear(String(article.updated_at).split("-")[0])
    setMonth(String(article.updated_at).split("-")[1])
 }

 if(skeletonStructure.current){
   setWidth(skeletonStructure.current.offsetWidth)
   setHeight(skeletonStructure.current.offsetHeight)
 }

  setTimeout(() => {
   setLoaded(true)
   }, 500) 
 
},[skeletonStructure.current,props.mainNew[0]])

如果您未在[]中提供从属状态,则状态更新发生时将不会再次呈现它。并且如果您提供[]为空,那么use-effect将仅被调用一次。