2018年的六一儿童节已到,特此一篇来献给小盆友们。此处应该有掌声....
明猪不装暗逼.png
写在前面:
首先,什么是TypeScript?
官方原话:TypeScript is a typed superset of JavaScript that complies to plain JavaScript. Any host. Any OS. Open source.
TypeScript是JavaScript类型的超集(强类型版本),它可以编译成纯的JavaScript,它可以再任何浏览器,任何计算机和任何操作系统上运行,并且开源。
嗯,是的,你可以理解为TypeScript硬是把JavaScript(弱类型语言)"掰弯"了,变成强类型语言;强类语言的优势在于静态类型的检查,TypeScript虽然是强类型的语言,但是如果对象被声明为any类型,就会忽略所有的类型检查。这种灵活的结构保证了它整体有强类语言检查优势的同时,在一些细节问题上保持了弱类型的灵活。
1.为了能够快速搭建应用,我们将使用create-react-app官方脚手架为基础进行扩展。
创建一个项目(TypeScript版本)
npx create-react-app 应用名称 --scripts-version=react-scripts-ts
2.安装所需依赖包
yarn add history @types/history react-router-dom @types/react-router-dom react-router-redux @types/react-router-redux redux-actions @types/redux-actions redux-thunk @types/redux-thunk redux --D
*注意:
(1).redux 已经包含TypeScript包
(2).redux-thunk:2.20目前会报语法错误,解决方法:
修改node_modules/redux-thunk/index.d.ts
import { Middleware, Dispatch, Action, AnyAction } from 'redux';export type ThunkAction<R, S, A extends Action = AnyAction, E = {}> = { (dispatch: Dispatch<A, S>, getState: () => S, extraArgument: E): R } declare module 'redux' { export interface Dispatch<A extends Action = AnyAction, S = {}> { <R, E>(thunk: ThunkAction<R, S, A, E>): R } } declare const thunk: Middleware & { withExtraArgument(extraArgument: any): Middleware; };export default thunk;
3.开始编码
(1) 新建一个models.ts
// store中初始状态的接口声明export interface ITodoModel { id?: number; text: string; completed: boolean; }
(2) 新建一个types.ts
// action 的唯一标识符 export const ADD_TODO = 'ADD_TODO';
(3) 新建一个anctions.ts
/** *** 因为store中状态是只读的(可以使用store.getState()来获取整个store的 状态) *** 要改变它里面的状态只能分发一个action去改变其属性 **/// createAction 让你可以轻松创建一个actionimport {createAction} from 'redux-actions';import {ITodoModel} from './models';import {ADD_TODO} from './types';const addTodo = createAction<ITodoModel, string>( ADD_TODO, (text: string) => ({text, completed: false}) );export { addTodo }
(4) 新建一个reducers.ts
import {handleActions} from 'redux-actions';import {ADD_TODO} from './types';import {ITodoModel} from './models'// 初始的状态,就像react中组件内的初始状态,只不过这个是全局的。const initialState: ITodoModel = { completed: true, id: 1, text: 'Use Redux', };export const todoReducer = handleActions<ITodoModel>({ [ADD_TODO]: (state: any, action: any) => { console.log('reducer->state:', state); console.log('reducer->action:', action); return {completed: true, text: action.payload.text, id: 2}; }, }, initialState);
(5) 开始组建store
store->initState.ts
import {ITodoModel} from '../containers/home/modules/models'; export interface IRootState { todo: ITodoModel; }
store->reducer.ts
import {combineReducers} from 'redux';import {todoReducer} from '../containers/home/modules/reducers';// 把前面的reducers combine 起来const rootReducer = combineReducers({ todo: todoReducer as any }); export default rootReducer;
store->reducer.ts
import {Store, createStore, applyMiddleware} from 'redux';import {routerMiddleware} from 'react-router-redux';import thunkMiddleware from 'redux-thunk';import rootReducer from './reducer';import {IRootState} from './initState';import {History} from 'history';export function configureStore(history: History, initialState?: IRootState): Store<IRootState> {// store 中间件,根据个人需求添加const middleware = applyMiddleware( thunkMiddleware, routerMiddleware(history)); return createStore( rootReducer as any, initialState as any, middleware ) as Store<IRootState>; }
(6) 修改入口文件index.tsx
import * as React from 'react';import * as ReactDOM from 'react-dom';import {Provider} from 'react-redux';import registerServiceWorker from './registerServiceWorker';import Routers from './containers/Routers';import createHistory from 'history/createBrowserHistory'import {configureStore} from './store';const history = createHistory();const store = configureStore(history); ReactDOM.render( <Provider store={store}> <Routers/> </Provider> ,document.getElementById('root') as HTMLElement ); registerServiceWorker();
(7) 如何使用?
import * as React from 'react';import {Dispatch} from 'redux';import {connect} from 'react-redux';import {addTodo} from './containers/home/modules/anctions';import {Button} from 'antd';import './App.less'; interface IAppProps { addTodo?: any; todos?: any; }class App extends React.Component<IAppProps> {constructor(props: any) { super(props); }// 组件内分发action,改变store中的属性值public change = () => { const myName = '我叫二白'; this.props.addTodo(myName) };// 把store绑定在视图层上public render() { console.log(this.props); return ( <div className='App'> <div>{this.props.todos.todo.text}</div> <Button onClick={() => this.change()}>redux点击一下</Button> </div> ); } }// mapStateToProps(state, ownProps) 方法允许我们将store中的数据作为 // props绑定到组件中,只要store更新了就会调用mapStateToProps方法,// mapStateToProps返回的结果必须是object对象,该对象中的值将会更组件中;const mapStateToProps = (state: any) => ({todos: state });// mapDispatchToProps(dispatch, [ownProps]) 第二个参数允许我们将action // 作为props绑定到组件中,// mapDispatchToProps希望你返回包含对应action的object对象; const mapDispatchToProps = (dispatch: Dispatch<any>) => { return { addTodo: (payload: string) => dispatch(addTodo(payload)), } };export default connect(mapStateToProps, mapDispatchToProps)(App);
作者:黄二白
链接:https://www.jianshu.com/p/c5001d40ab25
共同学习,写下你的评论
评论加载中...
作者其他优质文章