编写高质量的react代码

组件结构

// 使用函数组件和 Hooks
const MyComponent = ({ prop1, prop2 }) => {
  const [state, setState] = useState(initialState);
  
  useEffect(() => {
    // 副作用逻辑
  }, [dependencies]);

  return (
    <div>
      {/* JSX 结构 */}
    </div>
  );
};

代码分割和懒加载

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

性能优化

// 使用 useMemo 缓存计算结果
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

// 使用 useCallback 缓存函数
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);

// 使用 React.memo 避免不必要的重渲染
const MemoizedComponent = React.memo(MyComponent);

状态管理

// 使用 useReducer 管理复杂状态
const [state, dispatch] = useReducer(reducer, initialState);

// 使用 Context API 进行全局状态管理
const MyContext = React.createContext(defaultValue);

类型检查(使用 TypeScript 或 PropTypes)

interface Props {
  name: string;
  age: number;
}

const MyComponent: React.FC<Props> = ({ name, age }) => {
  // ...
};

错误边界

class ErrorBoundary extends React.Component {
  // ...错误处理逻辑
}

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>

测试

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

test('component renders correctly', () => {
  const { getByText } = render(<MyComponent />);
  expect(getByText('Hello')).toBeInTheDocument();
});

代码风格和最佳实践

使用 ESLint 和 Prettier 保持代码风格一致
遵循 React 的最佳实践,如使用 key 属性、避免过度使用 state 等

测试

测试类型
a. 单元测试:测试独立的函数或组件
b. 集成测试:测试多个组件的交互
c. 端到端测试:模拟用户行为,测试整个应用流程

常用测试工具
Jest:JavaScript 测试框架
React Testing Library:用于测试 React 组件
Enzyme:Airbnb 的 React 测试工具(虽然现在更推荐 React Testing Library)

测试示例


```javascript
// MyComponent.tsx
import React from 'react';

interface Props {
  name: string;
}

const MyComponent: React.FC<Props> = ({ name }) => {
  return <div>Hello, {name}!</div>;
};

export default MyComponent;

// MyComponent.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  test('renders greeting with name', () => {
    render(<MyComponent name="Alice" />);
    expect(screen.getByText('Hello, Alice!')).toBeInTheDocument();
  });
});

测试异步操作

// AsyncComponent.tsx
import React, { useState, useEffect } from 'react';

const AsyncComponent = () => {
  const [data, setData] = useState<string | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('https://api.example.com/data');
      const result = await response.json();
      setData(result.message);
    };
    fetchData();
  }, []);

  return <div>{data ? data : 'Loading...'}</div>;
};

// AsyncComponent.test.tsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import AsyncComponent from './AsyncComponent';

jest.mock('node-fetch');

describe('AsyncComponent', () => {
  test('renders data after fetch', async () => {
    const mockFetch = jest.fn().mockResolvedValue({
      json: () => Promise.resolve({ message: 'Hello from API' }),
    });
    global.fetch = mockFetch;

    render(<AsyncComponent />);
    
    expect(screen.getByText('Loading...')).toBeInTheDocument();
    
    await waitFor(() => {
      expect(screen.getByText('Hello from API')).toBeInTheDocument();
    });
  });
});

测试用户交互

// Counter.tsx
import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

// Counter.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

describe('Counter', () => {
  test('increments count when button is clicked', () => {
    render(<Counter />);
    
    const button = screen.getByText('Increment');
    fireEvent.click(button);
    
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });
});

测试覆盖率

// package.json
{
  "scripts": {
    "test": "react-scripts test",
    "test:coverage": "react-scripts test --coverage --watchAll=false"
  }
}

持续集成

# .github/workflows/test.yml
name: Run Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'
      - run: npm ci
      - run: npm test
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值