SonarQube 使用 MUI/TS“不要在渲染期间定义组件”,但无法将组件作为 prop 发送

Lui*_*uin 6 javascript reactjs sonarqube react-hooks react-typescript

我在 sonarqube 扫描期间收到以下错误:

\n
\n

不要在渲染期间定义组件。React 将在每次渲染时看到一个新的组件类型,并销毁整个 subtree\xe2\x80\x99s DOM 节点和状态。相反,将此组件定义移出父组件 \xe2\x80\x9cSectionTab\xe2\x80\x9d 并将数据作为 props 传递。如果您想允许在 props 中创建组件,请将 allowedAsProps 选项设置为 true。

\n
\n

在此输入图像描述

\n

我知道它说我应该将组件作为父级的道具发送,但我不想每次我想使用此组件时都发送图标,是否有其他方法可以解决此问题?

\n
import Select from "@mui/material/Select";\nimport { FontAwesomeIcon } from "@fortawesome/react-fontawesome";\nimport { faAngleDown } from "@fortawesome/pro-solid-svg-icons/faAngleDown";\n\nconst AngleIcon = ({ props }: { props: any }) => {\n  return (\n    <FontAwesomeIcon\n      {...props}\n      sx={{ marginRight: "10px" }}\n      icon={faAngleDown}\n      size="xs"\n    />\n  );\n};\n\nconst SectionTab = () => {\n  return (\n    <Select\n      id="course_type"\n      readOnly={true}\n      IconComponent={(props) => <AngleIcon props={props} />}\n      variant="standard"\n      defaultValue="cr"\n      disableUnderline\n    />\n  );\n};\n\nexport default SectionTab;\n
Run Code Online (Sandbox Code Playgroud)\n

Ori*_*ori 9

你能做什么:

  1. 将组件作为 prop 发送:

    IconComponent={AngleIcon}
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您需要动态地将任何内容传递给组件,您可以使用以下方式将其包装useCallback:

    const SectionTab = () => {
        const IconComponent = useCallback(props => <AngleIcon props={props} />, []);
    
       return (
         <Select
           id="course_type"
           readOnly={true}
           IconComponent={IconComponent}
           variant="standard"
           defaultValue="cr"
           disableUnderline
         />
       );
     };
    
    Run Code Online (Sandbox Code Playgroud)

这将生成一个稳定的组件,但它是相当多余的,除非您需要传递任何其他内容,而不是通过props. 这样的话,每当外部值发生变化时,就会产生一个新的组件,这将使其再次变得不稳定。您可以使用 refs 传递值而不生成新组件,但组件的树不会重新渲染以反映 ref 中的更改。

const SectionTab = () => {
  const [value, setValue] = useState(0);
  
  const IconComponent = useCallback(
    props => <AngleIcon props={props} value={value} />
  , []);

  return (
    <Select
      id="course_type"
      readOnly={true}
      IconComponent={IconComponent}
      variant="standard"
      defaultValue="cr"
      disableUnderline
    />
  );
};
Run Code Online (Sandbox Code Playgroud)