如何在 React JS 中基于条件不要重复自己(干)原则?

how to do condition based don't repeat yourself (dry) principle in React JS?

组件使用方式:

  import React from "react";
  import MyAvatars from "../../components/MyAvatar/MyAvatars";

  const About = () => {
   return (
  
    <MyAvatars
      topType={[true, 1000]}
      accessoriesType={[true, 1200]}
      facialHairType={["blank"]}
    />
   );
 };

 export default About;

这是我的代码。 我目前正在研究这个。

代码:

  import React from "react";
  import Avatar from "avataaars";
  import { Top, Accessories, FacialHair } from "./avatarThings";

  const MyAvatar = ({ topType, facialHairType }) => {
  
  const [avatar, setAvatar] = React.useState({
      avatarStyle: "Circle",
      topType: "ShortHairDreads01",
      accessoriesType: "Blank",
      facialHairType: "Blank",
});


const topFunc = () =>{
    if (topType.length === 2) {
      const interval = setInterval(() => {
        setAvatar((prev) => {
          return {
            ...prev,
            topType:  Top[Math.floor(Math.random() * Top.length)],
          };
        });
      }, topType[1]); //this is time
      return () => clearInterval(interval);
    }
    setAvatar((prev) => {
      return {
        ...prev,
        topType: topType[0],
      };
    });
}

const FacialHairFunc = () =>{
      if (facialHairType.length === 2) {
      const interval = setInterval(() => {
        setAvatar((prev) => {
          return {
            ...prev,
            facialHairType: FacialHair[Math.floor(Math.random() * FacialHair.length)],
          };
        });
      }, facialHairType[1]);
      return () => clearInterval(interval);
    }
    setAvatar((prev) => {
      return {
        ...prev,
        facialHairType: facialHairType[0],
      };
    });
}

React.useEffect(() => {

  if (topType) {
    topFunc()
  }
  if (facialHairType) {
    FacialHairFunc()
  }

}, [])


return (
  <Avatar
    avatarStyle="Circle"
    topType={avatar.topType}
    accessoriesType={avatar.accessoriesType}
    hairColor={avatar.hairColor}
    facialHairType={avatar.facialHairType}
  />

 );
};

export default MyAvatar;

我是编程新手。 我目前正在创建一个有用的 open-source NPM 包.

这是它的代码。 一遍又一遍地重复相同的代码。

我希望我可以比这更容易地修改这段代码,但我不能。 人们很容易欣赏你。 我会用你为此编写的代码学习新东西。

如果你能帮上忙,我会很高兴。

请帮忙,让我也知道你的贡献

谢谢:)

有效计算随机属性的函数与更新头像状态的方面有些耦合。

我建议将每个选择随机属性并更新状态的“属性”函数转换为单个 React 钩子,该钩子采用属性数组和间隔,以及 returns 随机属性,然后简单地传递每个随机选择的属性直接添加到 Avatar 组件。没有令人信服的理由让您的组件具有中间 avatar 状态。

示例:

const getRandomAttribute = arr => arr[Math.floor(Math.random() * arr.length)];

const useRandomAttribute = (attributes = [], valueArr = []) => {
  const [attribute, setAttribute] = useState(() => {
    if (valueArr[0]) {
      return getRandomAttribute(attributes);
    }
  });

  useEffect(() => {
    let timerId;
    if (valueArr[0] && valueArr[1] > 0) {
      timerId = setInterval(() => {
        const attribute = getRandomAttribute(attributes);
        setAttribute(attribute);
      }, valueArr[1]);
    }
    return () => clearTimeout(timerId);
  }, [attributes, valueArr]);

  return attribute;
};

应用程序

import React from "react";
import Avatar from "avataaars";
import { Top, Accessories, FacialHair, ..... } from "./avatarThings";

const MyAvatar = ({ topType, facialHairType, accessoriesType, hairType }) => {
  const accessory = useRandomAttribute(Accessories, accessoriesType);
  const face = useRandomAttribute(FacialHair, facialHairType);
  const hair = useRandomAttribute(Hair, hairType);
  const top = useRandomAttribute(Top, topType);

  return (
    <Avatar
      avatarStyle="Circle"
      topType={top || "ShortHairDreads01"}
      accessoriesType={accessory || "Blank"}
      hairColor={hair || "BrownDark"}
      facialHairType={face || "Blank"}
      clotheType="Hoodie"
      clotheColor="Red"
      eyeType="Wink"
      eyebrowType="Default"
      mouthType="Smile"
      skinColor="Brown"
    />
  );
};

您可以从此处调整代码以获取间隔时间、其他 default/fallback 值等。

您是否可以只创建一个解析所需参数的函数:

import React from "react";
import Avatar from "avataaars";
import { Top, Accessories, FacialHair } from "./avatarThings";

const MyAvatar = ({ topType, facialHairType }) => {

const [avatar, setAvatar] = React.useState({
    avatarStyle: "Circle",
    topType: "ShortHairDreads01",
    accessoriesType: "Blank",
    facialHairType: "Blank",
});

const typeFunction = (type, AvatarComponent) =>{
    if (type.length === 2) {
        const interval = setInterval(() => {
            setAvatar((prev) => {
                return {
                    ...prev,
                    type: AvatarComponent[Math.floor(Math.random() * AvatarComponent.length)],
                };
            });
        }, type[1]);
        return () => clearInterval(interval);
    }
    setAvatar((prev) => {
        return {
            ...prev,
            type: type[0],
        };
    });
}

React.useEffect(() => {
    if (topType) {
        typeFunction(type, Top)
    }
    if (facialHairType) {
        typeFunction(facialHairType, FacialHair)
    }
}, [])


return (
        <Avatar
            avatarStyle="Circle"
            topType={avatar.topType}
            accessoriesType={avatar.accessoriesType}
            hairColor={avatar.hairColor}
            facialHairType={avatar.facialHairType}
        />
    );
};

export default MyAvatar;