如何重构此组件以避免重复?

时间:2019-08-01 18:06:18

标签: reactjs

我正在尝试重构此组件以避免重复。 depth0-4有5个级别,是一个道具。如您所见,根据深度的值,我想更改css className。到目前为止,我已经获得了每个深度级别的整个代码的副本。我还想根据preview道具是否未定义来更改是否显示preview。我在最佳方法方面感到困惑!有任何想法吗?预先感谢。

function Node({ type, name, depth, isEmptyFolder, preview, extension, handleClick }) {

  const classes = useStyles();
  const [anchorEl, setAnchorEl] = useState(null);

  function handlePopoverOpen(event) {
    setAnchorEl(event.currentTarget);
  }

  function handlePopoverClose() {
    setAnchorEl(null);
  }

  const open = Boolean(anchorEl);

  const renderNode = () => {
    if (depth === 0 && type === 'folder') {
      return (
        <div className="depth0" onClick={() => handleClick(type, depth, preview, isEmptyFolder)} >
          <FolderOpen style={{ fontSize: 50 }} />
          <div>
          {name}
          </div>
        </div>
      );
    }
    if (depth === 0 && type === 'file') {
      return (
        <div className="depth0" onClick={() => handleClick(type, depth, preview, isEmptyFolder)}>
          <FileCopy style={{ fontSize: 50 }} />
          <Typography
            aria-owns={open ? 'mouse-over-popover' : undefined}
            aria-haspopup="true"
            onMouseEnter={handlePopoverOpen}
            onMouseLeave={handlePopoverClose}
          >
            {name + extension} | Preview
        </Typography>
          <Popover
            id="mouse-over-popover"
            className={classes.popover}
            classes={{
              paper: classes.paper,
            }}
            open={open}
            anchorEl={anchorEl}
            anchorOrigin={{
              vertical: 'bottom',
              horizontal: 'left',
            }}
            transformOrigin={{
              vertical: 'top',
              horizontal: 'left',
            }}
            onClose={handlePopoverClose}
            disableRestoreFocus
          >
            <Typography>{preview}</Typography>
          </Popover>
        </div>
      );
    }
  }

  return (
    <>
      {renderNode()}
    </>
  );
}

2 个答案:

答案 0 :(得分:1)

您可以使用字符串文字来使用字符串内部的depth参数

className={`depth${depth}`}

这将导致depth = 0的结果为“ depth0”,depth = 4的结果为“ depth4”

对于预览问题,您可以使用条件渲染

{preview && (
   <Typography>{preview}</Typography>
)}

答案 1 :(得分:0)

不确定这是否是您要查找的内容,但无需重复<div className="depth0"....部分。

function Node({ type, name, depth, isEmptyFolder, preview, extension, handleClick }) {

  const classes = useStyles();
  const [anchorEl, setAnchorEl] = useState(null);

  function handlePopoverOpen(event) {
    setAnchorEl(event.currentTarget);
  }

  function handlePopoverClose() {
    setAnchorEl(null);
  }

  const open = Boolean(anchorEl);

  const renderNode = () => {
    let content;
    if (depth === 0 && type === 'folder') {
      content = (
        <>
          <FolderOpen style={{ fontSize: 50 }} />
          <div>
          {name}
          </div>
        </>
      );
    }
    if (depth === 0 && type === 'file') {
      content = (
        <>
          <FileCopy style={{ fontSize: 50 }} />
          <Typography
            aria-owns={open ? 'mouse-over-popover' : undefined}
            aria-haspopup="true"
            onMouseEnter={handlePopoverOpen}
            onMouseLeave={handlePopoverClose}
          >
            {name + extension} | Preview
        </Typography>
          <Popover
            id="mouse-over-popover"
            className={classes.popover}
            classes={{
              paper: classes.paper,
            }}
            open={open}
            anchorEl={anchorEl}
            anchorOrigin={{
              vertical: 'bottom',
              horizontal: 'left',
            }}
            transformOrigin={{
              vertical: 'top',
              horizontal: 'left',
            }}
            onClose={handlePopoverClose}
            disableRestoreFocus
          >
            <Typography>{preview}</Typography>
          </Popover>
        </>
      );
    }
    return (
      <div className="depth0" onClick={() => handleClick(type, depth, preview, isEmptyFolder)} >
        {content}
      </div>
    );
  }

  return (
    <>
      {renderNode()}
    </>
  );
}