返回

用 TypeScript 编写更优美的 React 代码:7 大妙招

前端

巧用 TypeScript,编写更优美的 React 代码:7 大妙招

干净的代码不仅仅是能够正常运行的代码。它是一种经过精心组织、易于阅读、易于理解且易于维护的代码。接下来,让我们来看看编写干净 React 代码的一些最佳实践。遵循这些原则,让你在享受假期时也能安心。

1. 组件职责明确

每个组件都应该只负责一项特定任务。这样可以提高代码的可读性和可维护性。例如,一个按钮组件应该只处理按钮的行为,而不是控制整个页面的状态。

// Bad
const Button = () => {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      点击 {count} 次
    </button>
  );
};

// Good
const Button = ({ onClick }) => {
  return <button onClick={onClick}>按钮</button>;
};

2. 状态管理

在 React 中,状态管理是至关重要的。使用状态管理库,如 Redux 或 Zustand,可以让你集中控制应用程序的状态,避免组件之间的不必要的耦合。

// Bad
const App = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <Button onClick={() => setCount(count + 1)} />
      <p>计数:{count}</p>
    </div>
  );
};

// Good
const App = () => {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <Button onClick={() => dispatch({ type: 'INCREMENT' })} />
      <p>计数:{count}</p>
    </div>
  );
};

3. 适当使用 Hooks

Hooks 是 React 中强大的工具,但它们也可能导致代码混乱。为了保持代码整洁,请遵循以下准则:

  • 每个组件只使用必需的 Hooks。
  • 避免在 Hooks 之间传递状态或道具。
  • 始终使用 eslint-plugin-react-hooks 插件来检查 Hooks 的正确使用。
// Bad
const Component = () => {
  const [count, setCount] = useState(0);
  const [visible, setVisible] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    if (error) {
      setVisible(false);
    }
  }, [error]);

  return (
    <div>
      {/* ... */}
    </div>
  );
};

// Good
const Component = () => {
  const [state, setState] = useState({ count: 0, visible: false, error: null });

  useEffect(() => {
    if (state.error) {
      setState(prevState => ({ ...prevState, visible: false }));
    }
  }, [state.error]);

  return (
    <div>
      {/* ... */}
    </div>
  );
};

4. 编写可重用的组件

可重用组件可以提高代码的效率和一致性。通过将通用功能提取到可重用组件中,你可以减少重复代码并促进组件之间的松散耦合。

// Bad
const Header = () => {
  return (
    <header>
      <h1>我的应用</h1>
      <nav>
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
      </nav>
    </header>
  );
};

const Footer = () => {
  return (
    <footer>
      <p>版权所有 &copy; 2023</p>
    </footer>
  );
};

// Good
const Header = () => {
  return (
    <Layout>
      <h1>我的应用</h1>
      <nav>
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
      </nav>
    </Layout>
  );
};

const Footer = () => {
  return (
    <Layout>
      <p>版权所有 &copy; 2023</p>
    </Layout>
  );
};

const Layout = ({ children }) => {
  return (
    <header>
      {children}
    </header>
  );
};

5. 遵循命名约定

一致的命名约定有助于提高代码的可读性和可维护性。对于 React 组件,遵循以下命名约定:

  • 组件类:PascalCase
  • 组件函数:camelCase
  • 道具:camelCase
  • 状态:camelCase
// Bad
const mycomponent = () => {
  const myprop = 10;
  const myState = useState(0);

  return (
    <div>
      {/* ... */}
    </div>
  );
};

// Good
const MyComponent = () => {
  const myProp = 10;
  const myState = useState(0);

  return (
    <div>
      {/* ... */}
    </div>
  );
};

6. 编写测试用例

编写测试用例可以确保你的代码按预期工作,并随着时间的推移保持稳定。使用测试框架,如 Jest 或 React Testing Library,编写测试用例,以验证组件的行为和状态。

import { render, fireEvent } from '@testing-library/react';

// Bad
test('按钮点击后计数器增加', () => {
  const { getByText } = render(<Button />);
  const button = getByText('点击');

  fireEvent.click(button);
  expect(getByText('计数:1')).toBeInTheDocument();
});

// Good
test('按钮点击后计数器增加', () => {
  const { getByText } = render(<Button />);
  const button = getByText('点击');

  fireEvent.click(button);
  expect(getByText('计数:1')).toBeInTheDocument();

  fireEvent.click(button);
  expect(getByText('计数:2')).toBeInTheDocument();
});

7. 持续集成和持续交付

持续集成和持续交付 (CI/CD) 是一组实践,可以自动化构建、测试和部署代码。通过设置 CI/CD 管道,你可以确保代码在合并到主分支之前得到正确构建和测试。

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [ main ]

jobs:
  build-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '16'
      - run: npm install
      - run: npm test

遵循这些最佳实践,你可以编写干净的、易于维护的 React 代码,从而提高应用程序的整体质量和可持续性。祝你编码愉快!