在Reaction和Material-UI中使用百分比和文本的循环加载器

2022-06-23 00:00:00 reactjs css react-hooks material-ui
我这里有一个CircularLoader使用材料用户界面。 我唯一的问题是,如果变量是indeterminate,则按原样显示加载器,而如果是determinate,则按原样显示加载器中的百分比和文本。

Codesandbox:CLICK HERE

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;

解决方案

我认为最好将这些组件分开(因为它们有不同的道具)。但如果您希望它们位于同一组件中,则需要向determinate变量提供一个从0到100的动态值。请参阅文档source code example。

在您的示例中,您可以在呈现哪个变量之间进行三元选择,作为一个快速演示,以下内容应该可以工作(请注意,出于演示目的,我将忽略Value Prop并使用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传递下来,并在CircularProgress组件中使用它(它应该是链接到实际加载进度状态的某个动态值)。

Link to Sandbox

相关文章