发布于 2026-01-06 0 阅读
0

通过这 5 个技巧提升你的 React 技能 DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

通过这 5 个技巧提升你的 React 技能

由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!

概括

我们将分析一段我们都见过(或迟早会遇到)的 JavaScript 代码。我会尝试对其进行一些改进,并解释我改进的原因。希望这对您有所帮助!

犯罪现场

function Othercomponent({ children, props }) {
  return <div {...props}>{children}</div>;
}
const MyComponent = ({
  id,
  text,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  const whichString = aType == "SomeString" ? "aString" : "bString";
  const whichNumber = aType == "SomeString" ? 123 : 321;
  const extraThing = "Hey! I am a string";
  if (containerOfThings && oneList && oneList.length > 1) {
    return (
      <ul>
        <Othercomponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[0]}
          extraThing={extraThing}
        >
          {text}
        </Othercomponent>
        <Othercomponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[1]}
          extraThing={extraThing}
        >
          {text}
        </Othercomponent>
        <Othercomponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[2]}
          extraThing={extraThing}
        >
          {text}
        </Othercomponent>
      </ul>
    );
  } else {
    return (
      <Othercomponent
        whichString={whichString}
        whichNumber={whichNumber}
        id={id}
        style={style}
        extraProps={extraProps}
        extraThing={extraThing}
        alt={text}
      >
        {text}
      </Othercomponent>
    );
  }
  return <></>;
};

const MyApp = (props) => (
  <MyComponent id={123} aType={"SomeString"} text="some content" {...props} />
);

好吧……请耐心听我说。我知道它现在看起来很糟糕。让我们一步一步地尝试改进它。

第一,保持一致性

在第一个组件中,我们使用 `@Component`而不是 PascalCase 命名<Othercomponent/>法来声明组件。而在第二个组件中,我们使用了箭头函数和 PascalCase 命名法。保持代码库的一致性非常重要,这样在创建另一个组件时,你和你的队友就不必再质疑组件的正确定义方式了。如果代码库保持一致,你的其他开发人员就能更好地了解当前状态和遵循的规则,从而避免在现有代码的基础上编写新代码时每一步都反复质疑。function XXXXX() { /* ... */ }<MyComponent/>


function Othercomponent({ children, props }) {
  return <div {...props}>{children}</div>;
}


const OtherComponent = ({ children, props }) => {
  return <div {...props}>{children}</div>;
};

结果

const OtherComponent = ({ children, props }) => {
  return <div {...props}>{children}</div>;
};

const MyComponent = ({
  id,
  text,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  const whichString = aType == "SomeString" ? "aString" : "bString";
  const whichNumber = aType == "SomeString" ? 123 : 321;
  const extraThing = "Hey! I am a string";
  if (containerOfThings && oneList && oneList.length > 1) {
    return (
      <ul>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[0]}
          extraThing={extraThing}
        >
          {text}
        </OtherComponent>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[1]}
          extraThing={extraThing}
        >
          {text}
        </OtherComponent>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[2]}
          extraThing={extraThing}
        >
          {text}
        </OtherComponent>
      </ul>
    );
  } else {
    return (
      <OtherComponent
        whichString={whichString}
        whichNumber={whichNumber}
        id={id}
        style={style}
        extraProps={extraProps}
        extraThing={extraThing}
        alt={text}
      >
        {text}
      </OtherComponent>
    );
  }
  return <></>;
};

const MyApp = (props) => (
  <MyComponent id={123} aType={"SomeString"} text="some content" {...props} />
);

#2 利用语言/框架特性

最近我在为前端工程师进行代码审查时,发现一个非常普遍的现象:我们不再熟悉框架的功能或语言提供的语法糖。

儿童作为道具

我们知道,在 React 组件内部编写的所有内容都是子组件,而子组件会作为 props 传递(你可以直接在组件内部传递,也可以通过children={'my child'}prop 传递)。因此,我们在实现组件时可以充分利用这一点。

无退货声明

我们可以利用 JavaScript 的单行函数特性,这些函数不需要任何return关键字。请充分利用这些由优秀开发者们贡献的功能!https://github.com/tc39/proposals

从:

const OtherComponent = (props) => {
  return <div {...props} />;
};


const MyComponent = ({
  id,
  text,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  // ..
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[0]}
          extraThing={extraThing}
        >
          {text}
        </OtherComponent>
  // ...

到:

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({
  id,
  children,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  // ...
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[0]}
          extraThing={extraThing}
        >
          {children}
        </OtherComponent>
  // ...

结果:

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({
  id,
  children,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  const whichString = aType == "SomeString" ? "aString" : "bString";
  const whichNumber = aType == "SomeString" ? 123 : 321;
  const extraThing = "Hey! I am a string";
  if (containerOfThings && oneList && oneList.length > 1) {
    return (
      <ul>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[0]}
          extraThing={extraThing}
        >
          {children}
        </OtherComponent>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[1]}
          extraThing={extraThing}
        >
          {children}
        </OtherComponent>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          id={id}
          style={style}
          extraProps={extraProps}
          alt={oneList[2]}
          extraThing={extraThing}
        >
          {children}
        </OtherComponent>
      </ul>
    );
  } else {
    return (
      <OtherComponent
        whichString={whichString}
        whichNumber={whichNumber}
        id={id}
        style={style}
        extraProps={extraProps}
        extraThing={extraThing}
        alt={children}
      >
        {children}
      </OtherComponent>
    );
  }
  return <></>;
};

const MyApp = (props) => (
  <MyComponent id={123} aType={"SomeString"} {...props}>
    some content
  </MyComponent>
);

#3 无缘无故地直白

有些人喜欢主张我们应该始终显式地定义所有属性,每个组件都应该解析所有属性。我理解这种做法在某些情况下是可取的,但在大多数情况下,它只会增加代码的冗余。如果你确实需要这样做,请考虑迁移到 TypeScript(或者如果你只是想编写更好的 JavaScript 代码)。在我们的示例中,我们可以隐式地定义很多东西,因为我们解析了一些我们从未用到且并不关心的变量。

从:

// ...
const MyComponent = ({
  id,
  children,
  style,
  extraProps,
  oneList,
  containerOfThings,
  aType,
}) => {
  // ...
  <OtherComponent
    whichString={whichString}
    whichNumber={whichNumber}
    id={id}
    style={style}
    extraProps={extraProps}
    alt={oneList[0]}
    extraThing={extraThing}
  >
    {children}
  </OtherComponent>

到:

// ...
const MyComponent = ({ oneList, containerOfThings, aType, ...props }) => {
  // ...
  <OtherComponent
    whichString={whichString}
    whichNumber={whichNumber}
    alt={oneList[0]}
    extraThing={extraThing}
    {...props}
  />

结果:

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({ oneList, containerOfThings, aType, ...props }) => {
  const whichString = aType == "SomeString" ? "aString" : "bString";
  const whichNumber = aType == "SomeString" ? 123 : 321;
  const extraThing = "Hey! I am a string";
  if (containerOfThings && oneList && oneList.length > 1) {
    return (
      <ul>
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          alt={oneList[0]}
          extraThing={extraThing}
          {...props}
        />
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          alt={oneList[1]}
          extraThing={extraThing}
          {...props}
        />
        <OtherComponent
          whichString={whichString}
          whichNumber={whichNumber}
          alt={oneList[2]}
          extraThing={extraThing}
          {...props}
        />
      </ul>
    );
  } else {
    return (
      <OtherComponent
        whichString={whichString}
        whichNumber={whichNumber}
        alt={oneList[0]}
        extraThing={extraThing}
        {...props}
      />
    );
  }
  return <></>;
};

const MyApp = (props) => (
  <MyComponent
    id={123}
    aType={"SomeString"}
    {...props}
    containerOfThings={true}
    oneList={["alt1", "alt2", "alt3"]}
  >
    some content
  </MyComponent>
);

#4 减少逻辑分支/降低代码出错率

我们都喜欢三元运算符和不必要的变量,我懂。我也掉进过这个陷阱,为了让某个功能正常运行,就觉得用if三元运算符检查或赋值是解决办法。但大多数时候并非如此。这样做只会增加你实现代码完整/良好测试覆盖率所需的时间。

当我们偶尔添加这些逻辑分支时,我们会犯一些愚蠢的错误,例如编写无法访问的代码,或者使我们的代码变得比应该的更复杂。

移除三元运算符

减少三元条件语句逻辑分支的一个巧妙技巧是使用映射(也可以称为哈希/对象)。你可以把它们看作是配置辅助工具。😇

从:

// ...
const whichString = aType == "SomeString" ? "aString" : "bString";
const whichNumber = aType == "SomeString" ? 123 : 321;
// ...
<OtherComponent
  whichString={whichString}
  whichNumber={whichNumber}
  alt={oneList[0]}
  extraThing={extraThing}
  {...props}
/>;
// ...

到:

// ...
const valuesMap = {
  SomeString: { str: "aString", num: 123 },
  OtherString: { str: "bString", num: 321 },
};
// ...
<OtherComponent
  whichString={valuesMap[aType].str}
  whichNumber={valuesMap[aType].num}
  alt={oneList[0]}
  extraThing={extraThing}
  {...props}
/>;
// ...

结果:

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({ oneList, containerOfThings, aType, ...props }) => {
  const valuesMap = {
    SomeString: { str: "aString", num: 123 },
    OtherString: { str: "bString", num: 321 },
  };
  const extraThing = "Hey! I am a string";
  if (containerOfThings && oneList && oneList.length > 1) {
    return (
      <ul>
        <OtherComponent
          whichString={valuesMap[aType].str}
          whichNumber={valuesMap[aType].num}
          alt={oneList[0]}
          extraThing={extraThing}
          {...props}
        />
        <OtherComponent
          whichString={valuesMap[aType].str}
          whichNumber={valuesMap[aType].num}
          alt={oneList[1]}
          extraThing={extraThing}
          {...props}
        />
        <OtherComponent
          whichString={valuesMap[aType].str}
          whichNumber={valuesMap[aType].num}
          alt={oneList[2]}
          extraThing={extraThing}
          {...props}
        />
      </ul>
    );
  } else {
    return (
      <OtherComponent
        whichString={valuesMap[aType].str}
        whichNumber={valuesMap[aType].num}
        alt={oneList[0]}
        extraThing={extraThing}
        {...props}
      />
    );
  }
  return <></>;
};

const MyApp = (props) => (
  <MyComponent
    id={123}
    aType={"SomeString"}
    {...props}
    containerOfThings={true}
    oneList={["alt1", "alt2", "alt3"]}
  >
    some content
  </MyComponent>
);

简化操作,移除条件语句

函数式编程(FP)范式出现并再次流行起来已经好几年了。因此,现在是时候停止使用函数ifs式编程,并提高代码质量了。

在这个例子中,我们可以看到存在不必要的返回值,这个例子虽然很愚蠢或显而易见,但我保证你肯定读过或正在读过一些带有无用条件的代码。

如果我们能找到办法让所有场景都使用相同的 HTML 结构,你的代码就会变得极其简洁。如果你还没找到明确的实现方法,可能需要提升一下你的 CSS 技能。

结果:

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({ oneList = [], aType, ...props }) => {
  const valuesMap = {
    SomeString: { str: "aString", num: 123 },
    OtherString: { str: "bString", num: 321 },
  };
  const extraThing = "Hey! I am a string";
  return (
    <ul>
      {oneList.map((item) => (
        <OtherComponent
          whichString={valuesMap[aType].str}
          whichNumber={valuesMap[aType].num}
          alt={item}
          key={item}
          extraThing={extraThing}
          {...props}
        />
      ))}
    </ul>
  );
};

const MyApp = (props) => (
  <MyComponent
    id={123}
    aType={"SomeString"}
    {...props}
    containerOfThings={true}
    oneList={["alt1", "alt2", "alt3"]}
  >
    some content
  </MyComponent>
);

#5 React 应用中的常量

我给这篇文章的最后一个建议是:检查你的常量!

务必将它们放在 React 组件之外,这样每次调用组件时就不需要重新声明它们。此外,为 props 设置默认值,可以让所有人知道组件的默认行为,从而节省时间。

结果:

const STRING_TYPES = { SomeString: "SomeString", OtherString: "OtherString" };

const valuesMap = {
  SomeString: { whichString: "aString", whichNumber: 123 },
  OtherString: { whichString: "bString", whichNumber: 321 },
};

const extraThing = "Hey! I am a string";

const OtherComponent = (props) => <div {...props} />;

const MyComponent = ({
  aType = STRING_TYPES.SomeString,
  oneList = [],
  ...props
}) => (
  <ul>
    {oneList.map((item) => (
      <OtherComponent
        alt={item}
        key={item}
        extraThing={extraThing}
        {...valuesMap[aType]}
        {...props}
      />
    ))}
  </ul>
);

const MyApp = (props) => (
  <MyComponent
    id={123}
    aType={STRING_TYPES.SomeString}
    containerOfThings={true}
    oneList={["alt1", "alt2", "alt3"]}
    {...props}
  >
    some content
  </MyComponent>
);

结束了!

希望这对你们有帮助!

祝好,注意安全!

文章来源:https://dev.to/grekz/improve-your-react-skills-with-these-5-tips-2c65