react-redux-typescript-guide项目实战:RealWorld App从开发到部署
·
react-redux-typescript-guide项目实战:RealWorld App从开发到部署
项目概述
react-redux-typescript-guide是一个全面的指南项目,旨在帮助开发者使用TypeScript构建类型安全的React和Redux应用。该项目提供了丰富的代码示例、最佳实践和完整的开发流程,从环境搭建到应用部署,全方位覆盖了现代前端开发的各个方面。
环境准备
项目克隆
首先,克隆项目到本地开发环境:
git clone https://gitcode.com/gh_mirrors/re/react-redux-typescript-guide
cd react-redux-typescript-guide
安装依赖
项目使用npm作为包管理工具,安装所有依赖:
npm install
开发环境配置
项目提供了完整的开发配置文件,包括:
- TypeScript配置:tsconfig.json
- Jest测试配置:configs/jest.config.json
- ESLint配置:项目中包含ESLint配置,确保代码质量
项目结构解析
项目采用模块化结构设计,主要包含以下目录和文件:
react-redux-typescript-guide/
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CONTRIBUTORS.md
├── LICENSE
├── README.md
├── README_SOURCE.md
├── configs/ # 配置文件目录
├── docs/ # 文档目录
├── generate-readme.js # README生成脚本
├── package-lock.json
├── package.json
└── playground/ # 示例代码目录
├── public/ # 静态资源
├── src/ # 源代码
│ ├── api/ # API相关代码
│ ├── components/ # React组件
│ ├── connected/ # Redux连接组件
│ ├── context/ # React Context
│ ├── features/ # 应用功能模块
│ ├── hoc/ # 高阶组件
│ ├── hooks/ # 自定义Hooks
│ ├── layout/ # 布局组件
│ ├── models/ # 类型定义
│ ├── routes/ # 路由配置
│ ├── services/ # 服务
│ └── store/ # Redux Store
└── styleguide/ # 样式指南
核心代码位于playground/src目录下,包含了各种React组件、Redux相关代码和工具函数。
核心功能实现
1. React组件开发
项目提供了多种类型的React组件示例,包括函数组件、类组件和通用组件。
函数组件示例
// [playground/src/components/fc-counter.tsx](https://link.gitcode.com/i/bf94f75859b64d12182f52fc29253614)
import * as React from 'react';
type Props = {
label: string;
count: number;
onIncrement: () => void;
};
export const FCCounter: React.FC<Props> = props => {
const { label, count, onIncrement } = props;
const handleIncrement = () => {
onIncrement();
};
return (
<div>
<span>
{label}: {count}
</span>
<button type="button" onClick={handleIncrement}>
{`Increment`}
</button>
</div>
);
};
类组件示例
// [playground/src/components/class-counter.tsx](https://link.gitcode.com/i/1092dfe23498403a84cf2090915d1109)
import * as React from 'react';
type Props = {
label: string;
};
type State = {
count: number;
};
export class ClassCounter extends React.Component<Props, State> {
readonly state: State = {
count: 0,
};
handleIncrement = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
const { handleIncrement } = this;
const { label } = this.props;
const { count } = this.state;
return (
<div>
<span>
{label}: {count}
</span>
<button type="button" onClick={handleIncrement}>
{`Increment`}
</button>
</div>
);
}
}
2. Redux状态管理
项目展示了如何使用TypeScript与Redux结合,实现类型安全的状态管理。
Store配置
// [playground/src/store/store.ts](https://link.gitcode.com/i/6d8ed712868b3ce5c4b7bc5779915c1f)
import { createStore, applyMiddleware, compose } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import { createEpicMiddleware } from 'redux-observable';
import { history } from './redux-router';
import { rootReducer } from './root-reducer';
import { rootEpic } from './root-epic';
export function configureStore() {
const epicMiddleware = createEpicMiddleware();
const composeEnhancers =
(window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(routerMiddleware(history), epicMiddleware))
);
epicMiddleware.run(rootEpic);
return store;
}
export const store = configureStore();
Action和Reducer示例
// [playground/src/features/todos/actions.ts](https://link.gitcode.com/i/98c693882320cf8597413d842c3aeabe)
import { createAction, createAsyncAction } from 'typesafe-actions';
import { Todo, TodosError } from './models';
export const fetchTodos = createAsyncAction(
'todos/FETCH_REQUEST',
'todos/FETCH_SUCCESS',
'todos/FETCH_FAILURE'
)<void, Todo[], TodosError>();
export const addTodo = createAction('todos/ADD_TODO')<Todo>();
export const toggleTodo = createAction('todos/TOGGLE_TODO')<number>();
// [playground/src/features/todos/reducer.ts](https://link.gitcode.com/i/e298f319f58c6c67fa617c79710a925a)
import { ActionType, createReducer } from 'typesafe-actions';
import { TodosState, TodosError } from './models';
import * as actions from './actions';
type TodosAction = ActionType<typeof actions>;
const initialState: TodosState = {
todos: [],
loading: false,
error: undefined,
};
export const todosReducer = createReducer<TodosState, TodosAction>(initialState)
.handleAction(actions.fetchTodos.request, state => ({
...state,
loading: true,
error: undefined,
}))
.handleAction(actions.fetchTodos.success, (state, action) => ({
...state,
loading: false,
todos: action.payload,
}))
.handleAction(actions.fetchTodos.failure, (state, action) => ({
...state,
loading: false,
error: action.payload,
}))
.handleAction(actions.addTodo, (state, action) => ({
...state,
todos: [...state.todos, action.payload],
}))
.handleAction(actions.toggleTodo, (state, action) => ({
...state,
todos: state.todos.map(todo =>
todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
),
}));
3. React Hooks使用
项目展示了React Hooks的使用,包括useState、useContext和useReducer等。
// [playground/src/hooks/use-state.tsx](https://link.gitcode.com/i/3d319bb0080ba6752e37645986c062aa)
import * as React from 'react';
type Props = { initialCount: number };
export default function Counter({ initialCount }: Props) {
const [count, setCount] = React.useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
</>
);
}
4. 异步数据流处理
项目使用redux-observable处理异步数据流:
// [playground/src/features/todos/epics.ts](https://link.gitcode.com/i/ad1eab87f049ca8889d3d9b51bf20efb)
import { Observable, of } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { catchError, map, switchMap } from 'rxjs/operators';
import { Epic } from 'redux-observable';
import { RootAction, RootState } from '../../store';
import { fetchTodos } from './actions';
import { API_URL } from '../../api';
export const fetchTodosEpic: Epic<RootAction, RootAction, RootState> = action$ =>
action$.pipe(
switchMap(() =>
ajax.getJSON<Todo[]>(`${API_URL}/todos`).pipe(
map(response => fetchTodos.success(response)),
catchError(error => of(fetchTodos.failure({ message: error.message })))
)
)
);
interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}
测试策略
项目使用Jest进行单元测试,确保代码质量和功能正确性:
// [playground/src/features/todos/reducer.spec.ts](https://link.gitcode.com/i/b029c6a7a4acb7cbdf3515bbae572925)
import { todosReducer } from './reducer';
import { fetchTodos, addTodo, toggleTodo } from './actions';
describe('todos reducer', () => {
it('should handle initial state', () => {
expect(todosReducer(undefined, {} as any)).toEqual({
todos: [],
loading: false,
error: undefined,
});
});
it('should handle fetchTodos.success', () => {
expect(
todosReducer(
{ todos: [], loading: true, error: undefined },
fetchTodos.success([{ id: 1, title: 'Test', completed: false }])
)
).toEqual({
todos: [{ id: 1, title: 'Test', completed: false }],
loading: false,
error: undefined,
});
});
// 更多测试...
});
构建与部署
构建项目
项目提供了npm脚本用于构建:
npm run build
部署选项
项目可以部署到各种静态网站托管服务,如Netlify、Vercel或GitHub Pages。部署前确保已运行构建命令生成优化后的静态文件。
总结与展望
通过react-redux-typescript-guide项目,我们学习了如何使用TypeScript构建类型安全的React和Redux应用。项目提供了丰富的示例代码和最佳实践,涵盖了现代前端开发的各个方面。
未来可以进一步扩展:
- 集成更多高级Redux模式,如Redux Toolkit
- 添加更多测试用例,提高代码覆盖率
- 优化构建流程,提高性能
- 集成更多现代前端工具和库
希望本指南能够帮助你更好地理解和应用React、Redux和TypeScript构建高质量的前端应用。
资源与参考
- 官方文档:README.md
- 组件示例:playground/src/components
- Redux示例:playground/src/features
- 自定义Hooks:playground/src/hooks
更多推荐

所有评论(0)