促进发展:专业发展的6条路径

在过去的六个月中,我一直在观察有抱负的React程序员的发展。在这段时间里,他们走过了一条难以置信的道路。他们的学习速度,对知识的渴望,对卓越的渴望-所有这些给我留下了深刻的印象。



他们是如何做到的呢?从那些没有外界帮助就无法开展公共关系的人到那些寻求帮助的人,他们又如何呢?是什么促使人们寻求建议,而人们愿意向他人提供建议呢?学生如何成为老师? 我问他们这些问题。这就是他们的回答。











1.使用ESLint和TypeScript



JavaScript是一种松散类型的编程语言。使用这种语言,我们可以无数种方式解决相同的问题。 JavaScript没有内置机制来保护我们免于编写错误的代码或性能不佳的代码。但是,幸运的是,我们可以通过使用两种工具进行静态代码分析来改善这种情况。这些是TypeScript和ESLint。



通过使用ESLint进行静态代码分析,我们可以在问题付诸生产之前确定问题。我们可以根据我们的标准检查代码。这提高了代码库的可维护性。



例如,您可以安装ESLint插件eslint-plugin-react-hooks...该插件将在下面的代码中注意到该问题,该代码看起来完全正常,并将通知我们我们违反使用钩子规则之一



//    ,    
  if (userName !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', userName);
    });
  }


TypeScript允许您使用静态类型系统来捕获相关的错误。使用TypeScript时,您可以使用功能强大的IntelliSense工具提示,使操作各种组件和库更快,更轻松。编写代码时出现的工具提示提供有关组件和库的内部机制的信息。这加快了重构速度,并鼓励使用通用编码规则。



擅长TypeScript的人不仅会成为更好的JavaScript程序员,而且最终会开始编写更好的React代码。



2.熟悉React钩子



自2019年2月推出以来,React Hooks实际上已经接管了React开发领域。尽管React团队说您不应该通过将旧代码转换成钩子来重构旧代码,但是如今,钩子几乎无处不在。



如果您想在React开发领域取得成功,那么您可以花时间去做的最好的时间就是深入学习钩子,以便您可以完全理解它们。



您需要某种副作用吗?如果是这样,那么钩子useEffect就是您最好的朋友。是否需要监视组件的状态并在状态更改时重新呈现它?看一眼useState... 需要在渲染之间存储和更新一些值,但是当这些值改变时不渲染吗?也许您需要了解DOM元素的高度或宽度?然后你的朋友就是这个useRef



例如,让我们看一下最简单的用例useEffect假设我们希望安排单击按钮时页面标题的更新(以副作用的形式)。您可以尝试解决以下问题:



useEffect(() => {
  document.title = `You clicked ${count} times`;
}); //    


通过使该钩子不在每个渲染器上运行,而是仅在变量更改时运行,因此易于优化count这是通过count在数组中包含依赖项来完成的



useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); //      count


您应该习惯使用最常见的钩子并创建自己的钩子。您还应该精通钩子的合理使用。例如,知道何时使用钩子似乎会useEffect导致重新渲染,而什么时候不渲染。



3.不要太早优化代码



关于钩子的讨论将我们引到了过早优化的主题。我经常看到有抱负的React开发人员竭尽全力使他们的代码尽可能快。 React代码通常使用钩子useMemo进行优化useCallback。但是,使用它们并不总是合理的。



让我们看一个简单的组件,该组件将一系列糖果信息作为props。该组件过滤数组并显示巧克力名称列表(它们的属性type等于字符串值chocolate)。



一些开发人员可能会强烈要求编写类似于以下所示代码的代码。他们可能会认为:“我只会在糖果的整体清单更改时更新巧克力清单。”实施此想法将导致难以阅读的帮助程序结构重载代码。



const Chocolate = (props) => {
  const chocolates = useMemo(
    () => props.candies.filter((candy) => candy.type === "chocolate"),
    [props.candies]
  );
  return (
    <>
      {chocolates.map((item) => (
        <p>{item.name}</p>
      ))}
    </>
  );
};


建议不要编写简单干净的代码,而不是创建这样的组件。在这种情况下,没有理由使用useMemo钩子useMemouseCallback仅应用于记录对系统造成很大负担的复杂操作的结果。



我建议推迟优化工作的开始,直到获得明确表明问题的应用程序性能度量。



您不应该在任何地方使用它,useCallbackuseMemo只是因为您最近在某个地方阅读了有关它们的信息。不要优化一切。最好等问题出现后再解决。不要解决不存在的问题。



4.知道何时创建新组件



我已经看到许多有抱负的React程序员在组件中实现了项目的业务逻辑,这些组件原本只是扮演演示角色。为了使您的代码尽可能地可重用,重要的是创建尽可能容易和方便地重用的组件。



为此,您需要努力保持表示组件与实现某种逻辑的组件之间的分离。以前,一种常见的技术是将组件分为“容器”和实际上的“组件”。但是这种方法逐渐失去了意义。



让我们看一下一个组件,该组件从某处加载项目列表并将其显示在页面上。请注意,这两个任务都在同一组件中实现。



const ListItems = () => {
  const items = React.useState([]);
  React.useEffect(() => {
    async function fetchItems() {
      await fetched = fetchItems();
      setItems(fetched);
    }
  });
return (
    <>
      {items.map((item) => (
        <div className="item-container">
          <img src={item.img} />
          <div className="name">{item.name}</div>
          <div className="author">{item.author}</div>
        </div>
      ))}
    </>
  );
};


采取“容器”路线可能很诱人。遵循这一愿望,我们将创建两个组件:



const ListContainer = () => {
  const items = React.useState([]);
  React.useEffect(() => {
    async function fetchItems() {
      await fetched = fetchItems();
      setItems(fetched);
    }
  });
return <List items={items} />;
};
const List = (props) => {
  return (
    <>
      {props.items.map((item) => (
        <div className="item-container">
          <img src={item.img} />
          <div className="name">{item.name}</div>
          <div className="author">{item.author}</div>
        </div>
      ))}
    </>
  );
};


但是在这种情况下,您应该采取不同的行动。即,您需要抽象出仅扮演表示角色的组件部分。结果将是两个组件-组件List(列表)和组件Item(元素):



const List = () => {
  const items = React.useState([]);
  React.useEffect(() => {
    async function fetchItems() {
      await fetched = fetchItems();
      setItems(fetched);
    }
  });
return (
    <>
      {items.map((item) => (
        <Item item={item} />
      ))}
    </>
  );
};
const Item = ({ item }) => {
  return (
    <div className="item-container">
      <img src={item.img} />
      <div className="name">{item.name}</div>
      <div className="author">{item.author}</div>
    </div>
  );
};


5.特别注意测试



测试技术水平的高低是区分大三学生和大四学生的原因。如果您不熟悉测试React应用程序,则可以查找和研究大量有关它的材料。



也许您曾经写过一些单元测试,但是您的经验不足以创建涵盖整个应用程序的集成测试吗?再次,这不应该打扰您,因为有无数资源可以帮助您填补知识空白和经验不足。



对于例如,这里是我的测试基于反应的全栈的应用程序的完整周期的文章。



6.区分应该使用局部状态和全局状态的情况



在这里,我们将讨论在React中管理应用程序状态的主题。有很多技术可以解决这个问题。例如,这是redux,mobx,recoil,API context等。列出它们甚至都不容易。



但是,无论您选择哪种状态管理技术,在决定使用全局或局部状态时,我经常会看到React初级人员感到困惑。不幸的是,没有明确的规则可以明确地做出这样的决定。但是仍然可以制定一些有关此问题的规则。即,为了确定是使用全局状态还是局部状态来存储某些数据,请回答以下问题:



  • 我们是否需要一些与我们的组件没有直接关系的组件才能使用其数据?例如,用户名可能出现在导航栏中和欢迎屏幕上。
  • 在应用程序页面之间导航时,数据是否应保留?
  • 许多组件使用相同的数据吗?


如果可以肯定地回答这些问题,那么可能值得利用全球状态。但是,我马上告诉您,您不应该在全局状态下存储有关菜单正在发生的事情的信息。在决定将数据存储在何处时,请尝试推测应用程序中不同位置使用了哪些数据,以及哪些数据可能只存储在组件内部。



结果



现在您知道了要在React开发领域专业发展应该采取哪些途径。



当我回想起我在React Junior时编写的代码时,我想到了一件事。我正在编写很难理解的过于复杂的代码。随着我积累了更多的经验,我开始注意到我的代码是如何变得更简单的。代码越简单越好。我的代码现在很容易理解,即使在编写六个月后,您仍然可以理解它,因为事实证明,其中已经存在错误,需要处理。



您知道React程序员的专业发展道路是什么?






All Articles