10 个技巧和窍门助你成为更优秀的 ReactJS 开发者

2025-05-26

10 个技巧和窍门助你成为更优秀的 ReactJS 开发者

介绍

好了,伙计们,是时候再写一篇文章来为您提供一些您可以立即用来改进 React 游戏的知识,以帮助您成为更好的 React 开发人员,编写更好的代码或在编码面试中表现出色。

在函数组件中使用 React Hooks

React v16.8 引入了 Hooks,这极大地提升了 React 中的函数式编程能力。有了 Hooks,你现在可以、也应该使用函数式组件来替代类组件了。但是等等……函数式组件和状态?还有生命周期方法呢?

别担心 - React Hooks 已经为你做好了准备。让我们来看一些例子:

class myComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: '',
    };
  }
  onChange = event => {
    this.setState({ value: event.target.value });
  };
  render() {
    return (
      <div>
        <h1>This is a random class component</h1>
        <input
          value={this.state.value}
          type="text"
          onChange={this.onChange}
        />
        <p>{this.state.value}</p>
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

这是使用类的传统方法。但是有了 Hook,我们现在可以使用 useState Hook 来实现:

const myComponent = () => {
  const [value, setValue] = React.useState('');
  const onChange = event => setValue(event.target.value);
  return (
    <div>
      <h1>This is a random functional component with state!</h1>
      <input value={value} type="text" onChange={onChange} />
      <p>{value}</p>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

看起来简单多了?确实如此!我们使用 useState Hook 将初始状态设置为空字符串 (''),它返回一个包含当前状态 (value) 的数组,并返回一个修改该状态的方法 (setValue)。我们还使用数组解构来访问 [value, setValue]。

默认情况下,函数式组件无法访问生命周期方法。但现在我们有了 hooks,useEffect Hook 可以帮我们解决这个问题。首先是使用类的传统方法:

class myComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: localStorage.getItem('someRandomValue') || '',
    };
  }
  componentDidUpdate() {
    localStorage.setItem('someRandomValue', this.state.value);
  }
  onChange = event => {
    this.setState({ value: event.target.value });
  };
  render() {
    return (
      <div>
        <h1>Just some random class component!</h1>
        <input
          value={this.state.value}
          type="text"
          onChange={this.onChange}
        />
        <p>{this.state.value}</p>
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

以下是使用 useEffect Hook 的相同示例:

const myComponent = () => {
  const [value, setValue] = React.useState(
    localStorage.getItem('someRandomValue') || '',
  );
  React.useEffect(() => {
    localStorage.setItem('someRandomValue', value);
  }, [value]);
  const onChange = event => setValue(event.target.value);
  return (
    <div>
      <h1>Some random functional component with state and side Effects!</h1>
      <input value={value} type="text" onChange={onChange} />
      <p>{value}</p>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

这有多棒?当传递的数组 [value] 中的一个值发生变化时,useEffect 就会运行。

这只是使用 React Hooks 的两个示例。还有很多其他的 Hooks,你甚至可以创建自己的自定义 Hooks。我认为每个 ReactJS 开发者都应该学习这个概念!

使用 React Context API 传递 Props

你可能已经遇到过这样的情况:你拥有深度嵌套的组件,需要将 props 从上层传递到下层,而中间的一些组件只是让这些 props 传递。你可以使用 React Context API,而不必逐一修改链中的每个组件。

在此示例中,我们在一个单独的文件中创建一个新的上下文,例如:

import React from 'react'

const AuthContext = React.createContext({})

export const AuthProvider = AuthContext.Provider
export default AuthContext
Enter fullscreen mode Exit fullscreen mode

然后我们需要包装父元素,因此我们希望使用我们创建的提供程序来分发道具的最高层:

import React from 'react'
import ChildComponent from './components/ChildComponent'
import { AuthProvider } from './context/AuthContext'

function ParentComponent() {
  const auth = { userId: '123456', loggedIn: true }

  return (
    <AuthProvider value={auth}>
      <ChildComponent />
    </AuthProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode

现在,ParentComponent 的所有子组件都可以使用 auth 作为 prop。是不是很酷?
接下来我们要做的就是在子组件中使用该 context。我将使用函数式组件和 useContext Hook 来实现:

import React, { useContext } from 'react'
import AuthContext from './context/AuthContext'

function ChildComponent() {
  const auth = useContext(AuthContext)

  console.log(auth) // { userId: '123456', loggedIn: true }

  return null
}
Enter fullscreen mode Exit fullscreen mode

如果嵌套了更多子组件,它们也可以访问上下文。太棒了!

样式组件

Styled-Components 实际上是 CSS-in-JS 库的一部分,它将 CSS 抽象到组件级别,仅使用 JavaScript 来描述样式。它们可以通过 ES6 模板字面量表示法使用反引号来创建,如下所示:

// install styled components with npm install styled-components

import styled from 'styled-components';

const MyButton = styled.button`

  background: ${props => props.primary ? "green" : "white"};
  color: ${props => props.primary ? "white" : "green"};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid green;
  border-radius: 3px;
`;

render(
 return {
  <div>
    <MyButton>Normal</MyButton>
    <MyButton primary>Primary</MyButton>
  </div>
 }
)
Enter fullscreen mode Exit fullscreen mode

现在,您有了一个自定义样式的按钮组件,可以在应用程序中随处使用,取代普通的 HTML 按钮。所有样式都经过封装,不会干扰 DOM 中的其他样式。这很神奇吧?

React 片段

长期以来,你必须将所有内容都包裹在 return 语句中,放入单个 div 中,以便 React 能够将其正确渲染到 DOM 中,或者使用数组表示法。示例:

const myComponent1 = () => {
  return 
   <div>
    <Card key="1" />,
    'Some Text',
    <Card key="2" title="someTitle" content="Just some Content" />
   </div>
}

const myComponent2 = () => {
  return [
    <Card key="1" />,
    'Some Text',
    <Card key="2" title="someTitle" content="Just some Content" />
  ]
}
Enter fullscreen mode Exit fullscreen mode

随着 React Fragments 的引入,您不再需要使用这两种方法中的任何一种,而是可以执行以下操作:

const myComponent1 = () => {
  return 
   <Fragment>
    <Card key="1" />,
    'Some Text',
    <Card key="2" title="someTitle" content="Just some Content" />
   </Fragment>
}
Enter fullscreen mode Exit fullscreen mode

甚至从 Babel 7 开始也是如此:

const myComponent1 = () => {
  return 
   <>
    <Card key="1" />,
    'Some Text',
    <Card key="2" title="someTitle" content="Just some Content" />
   </>
}
Enter fullscreen mode Exit fullscreen mode

这很酷吧?

使用错误边界

应用程序中出现错误是一回事,但如果它们出现在视图中,至少不应该破坏整个应用程序。为此,React 中已经实现了“错误边界”。这些组件本质上是可以用来包裹其他组件的。它们会在渲染过程中以及生命周期方法中捕获错误。通过 componentDidCatch 方法(请注意,目前还没有 React Hook 来实现此功能,因此您必须使用基于类的组件),您可以对错误做出响应,并渲染回退或记录错误。以下是一个简短的示例:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
componentDidCatch(error, info) {
    // using state to initiate a fallback UI render
    this.setState({ hasError: true });
    // You can also log the error, for example to a service
    logErrorToMyService(error, info);
  }
render() {
    if (this.state.hasError) {
      // Rendering the actual fallback UI
      return <h1>This error is unknown - too bad!.</h1>;
    }
    return this.props.children;
  }
}
Enter fullscreen mode Exit fullscreen mode

您现在可以像这样使用这个 ErrorBoundary 组件:

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

React 和 Typescript

Typescript 是一个非常热门的话题,也是开发者近期学习的首选之一。在新版本的 create-react-app (CRA) 中,它内置了对 Typescript 的支持。您只需在使用 CRA 创建新项目时添加 --typescript 标志,如下所示:

npm create-react-app my-app --typescript
Enter fullscreen mode Exit fullscreen mode

在 React 中使用 Typescript 的主要好处是:

  • 最新的 JavaScript 功能可用
  • 复杂类型定义的接口
  • VS Code 是为 TypeScript 制作的
  • 可读性和验证以避免开发过程中出现错误

以下是在功能性 React 组件中使用 TypeScript 的简单示例:

import * as React from 'react';

const MyComponent: React.FunctionComponent<{
  name: string
}> = (props) => {
  return <h1>{props.name}</h1>
}

export default myComponent;
Enter fullscreen mode Exit fullscreen mode

或者使用接口:

interface Props {
  name: string
}

const MyComponent: React.FunctionComponent<Props> = (props) => {
  return <h1>{props.name}</h1>
}
Enter fullscreen mode Exit fullscreen mode

如果您想在 2020 年学习一些新东西,一定要尝试一下 TypeScript!

Jest + Enzyme 用于测试

测试应用程序是每个开发人员都应该做的事情,而且在许多公司中也是强制性的。使用正确的设置,测试 React 应用程序会非常酷。一种广泛使用的设置是 Jest + Enzyme。来看看吧!

Jest 默认自带 create-react-app 包,它是一个测试运行器、断言库和模拟库。它还提供快照测试,基本上就是创建组件的渲染快照,并自动与之前的快照进行比较。如果两者不匹配,测试就会失败。
这对于单元测试和集成测试来说非常实用,但对于 React 应用的真实组件来说呢?Enzyme 是一个 React 组件测试库,由 Airbnb 开发和维护,是 Jest 的理想合作伙伴。

有了这些库,我们可以进行如下简洁的测试:

it("will render correctly", () => {
  const wrapper = shallow(
    <MyComponent />
  )
  expect(wrapper).toMatchSnapshot();
})
Enter fullscreen mode Exit fullscreen mode

测试某个组件的基本渲染行为。但我们还可以做更多的事情,例如测试 props:

// We need to mock zum props first

const user = {
  name: 'ThePracticalDev',
  email: 'TPD@dev.to',
  username: 'tpd',
  image: null
}

// Then the tests

describe ('<UserProfile />', () => {
  it ('contains h3', () => {
    const wrapper = mount(<UserProfile user={user} />)
    const value = wrapper.find('h3').text()
    expect(value).toEqual('ThePracticalDev')
  })
  it ('accepts user props', () => {
    const wrapper = mount(<UserProfile user={user} />);
    expect(wrapper.props().user).toEqual(user)
  })
})
Enter fullscreen mode Exit fullscreen mode

看起来很棒,对吧?而且,你还可以用这个设置做很多事情,比如模拟 API 调用或测试生命周期方法……

JSX 中的条件语句

编写 JSX 非常酷,也是 React 的主要功能之一。为了提升你的能力,你可以使用这个小技巧:

而不是使用

{ return loginAttempts < maxAttempts ? <MyComponent/> : null }
Enter fullscreen mode Exit fullscreen mode

你可以做一个短路评估

{ return loginAttempts < maxAttempts && <MyComponent/> }
Enter fullscreen mode Exit fullscreen mode

高阶组件

高阶组件 (HOC) 是 React 中一个高级概念,用于抽象共享代码,使其在需要时可访问。这个概念类似于 JavaScript 中的高阶函数,因此 HOC 本质上是接受组件并返回组件,但它们本身不是组件,而是函数。从抽象层面来看,它看起来像这样:

const MyNewComponent = (MyBaseComponent) => {
  // ... copy old component, add additional data/functionality and update
  return UpdatedComponent
}
Enter fullscreen mode Exit fullscreen mode

Redux 的“connect”就是一个很好的例子。更实际的例子如下:

const colorizeElement = Element => props => <Element {...props} color="blue" />

Enter fullscreen mode Exit fullscreen mode

首先,我们创建一个 HOC(colorizeElement),其中包含一个元素,该元素保留其所有 props,并获取一个颜色(蓝色)的新 props。我们可以使用该 HOC 创建一个蓝色的新按钮,如下所示:

const MyButton = () => {
  return <button>I am a Button</button>
}

const ColoredButton = colorizeElement(MyButton)

function MyComponent() {
  return (
    <div className="MyComponentClass">
      <h1>Hello you colored Button</h1>
      <ColoredButton />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

看起来很酷,对吧?

React DevTools

React DevTools 是一款非常酷的浏览器扩展程序,适用于 Chrome 和 Firefox,由 Facebook React 核心团队维护。版本 4 于 2019 年 8 月发布,对于任何 React 开发者来说,这款扩展程序都非常有用。
React 开发工具

它与 React 和 React Native 配合良好,并真正帮助您了解 React App 内部发生的情况。

真正酷的是,你可能没有意识到这一点 - 一些大公司,如 Airbnb 和 Netflix,正在使用 React,如果你访问他们的网站,你可以在浏览器控制台中找到有关他们网站的信息(如果你安装了 React DevTools):
Netflix React DevTools

看到大佬们的成果总是令人欣喜。Redux DevTools 也同样如此!

奖励:React 开发人员必备的 VS Code 扩展

好了,你已经一路走到这一步了。是时候来点小奖励了。我列出了一些最适合 React 开发者的 VS Code 扩展:

ES7 React/Redux/GraphQL/React-Native 代码片段

ES7 React/Redux/GraphQL/React-Native 代码片段

一个非常酷的扩展,下载量接近 400 万次,为您带来大量有关 React、Redux 和 GraphQL 的代码片段。

Jest / Jest 片段

笑话

Jest 片段

两个与 Jest 完美兼容的扩展,为您提供更好的测试代码片段

Typescript React 代码片段

Typescript React 代码片段

如果您使用 Typescript + React,这是一个很酷的扩展,可以为您提供帮助。

虽然这些是专门针对 React 开发的扩展,但您也应该使用一些更通用的扩展。如果您已经写了一篇关于2020 年前端开发者十大最佳 VS Code 扩展的文章,请务必也查看一下!

结论

好了,一切都结束了,本文就到这里。我希望能够为您提供一些见解,帮助您成为更优秀的 React 开发者,无论您是刚刚入门还是经验丰富的开发者。如果您也像我一样热衷于 Vue 开发,那么您应该看看我的另一篇文章《10 个技巧和窍门,助您成为更优秀的 VueJS 开发者》。我很乐意听取您的意见和其他重要方面,所以请随时发表评论,并关注我,了解更多后续文章!

文章来源:https://dev.to/simonholdorf/10-tips-tricks-that-will-make-you-a-better-reactjs-dev-4fhn
PREV
10 个技巧和窍门助你成为更优秀的 VueJS 开发者
NEXT
2021 年前端开发人员应该学习的 10 件事