React 和 Material-UI 中带有百分比和文本的循环加载器

IT技术 css reactjs react-hooks material-ui
2022-07-28 01:40:08

我这里有一个CircularLoader使用 Material UI。我唯一的问题是,如果变体indeterminate则按原样显示加载程序,没有百分比,而如果determinate显示加载程序内部的百分比和文本则按原样显示。

Codesandbox:点击这里

const CircularLoader = (props) => {
  const {
    height = "auto",
    color = "primary",
    text = "",
    value = 0,
    variant = "indeterminate"
  } = props;

  return (
    <Grid
      component="div"
      container
      justifyContent="center"
      alignItems="center"
      flexDirection="column"
      sx={{ height }}
    >
      <CircularProgress
        // variant={variant}
        // value={value}
        disableShrink
        color={color}
        thickness={4}
        sx={{ marginBottom: "0.5rem" }}
      />
      <Typography variant="body1" component="div" color={color}>
        {text}
      </Typography>
    </Grid>
  );
};
export default CircularLoader;
1个回答

我认为最好将这些组件分开(因为它们有不同的props)。但是如果你想让它们在同一个组件中,你需要为变量提供一个从 0 到 100 的动态determinate请参阅文档源代码示例

在您的情况下,您可以在要渲染的变体之间进行三元选择,作为快速演示,以下应该可以工作(注意我忽略了 value props并progress出于演示目的对其进行模拟):

import React from "react";
import Grid from "@mui/material/Grid";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import CircularProgress from "@mui/material/CircularProgress";
import Box from '@mui/material/Box';

const CircularLoader = ({
  height = "auto",
  color = "primary",
  text = "",
  value = 0,
  variant = "indeterminate"
}) => {
  const [progress, setProgress] = React.useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress((prevProgress) =>
        prevProgress >= 100 ? 0 : prevProgress + 10
      );
    }, 800);

    return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <Grid
      component="div"
      container
      justifyContent="center"
      alignItems="center"
      flexDirection="column"
      sx={{ height }}
    >
      {variant === "indeterminate" ? (
        <CircularProgress />
      ) : (
      <Stack spacing={2} direction="row">
       <Box sx={{ position: 'relative', display: 'inline-flex' }}>
        <CircularProgress variant="determinate" value={progress}/>
        <Box
        sx={{
          top: 0,
          left: 0,
          bottom: 0,
          right: 0,
          position: 'absolute',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <Typography variant="caption" component="div" color="text.secondary">
          {`${Math.round(progress)}%`}
        </Typography>
      </Box>
    </Box>
        </Stack>
      )}

      <Typography variant="body1" component="div" color={color}>
        {text}
      </Typography>
    </Grid>
  );
};
export default CircularLoader;

progress在这种情况下仅出于演示目的进行模拟,而您需要value通过 props 传递进度并在 CircularProgress 组件中使用它(它应该是与实际加载进度状态相关的一些动态值)。

沙盒链接