react+redux+ts
1. 初始化项目
yarn create react-app my-app --template typescript
2.安装依赖
yarn add redux react-redux redux-devtools-extension
3.创建store
- src/store/reducer/user.ts
export interface IUser {
id: number,
name: string
}
interface IState {
user: IUser
}
const initUserState: IState = {
user: {
id: 0,
name: ''
}
}
export enum IUserActionType {
INIT,
CHANGE,
}
const user = (state:IState = initUserState, action: { type: IUserActionType, payload: any }) => {
switch (action.type) {
case IUserActionType.INIT:
return state
case IUserActionType.CHANGE:
return {...state, ...action.payload}
default:
return state
}
}
export default user
- src/store/index.ts
import { combineReducers } from "redux";
import user from "./user";
export default combineReducers({user})
- src/store/index.ts
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import reducers from "./reducers";
export type rootState = ReturnType<typeof reducers>
const store = createStore(reducers, composeWithDevTools(applyMiddleware()))
export default store
4. 组件使用
- 类组件
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { rootState } from './store'
import { IUser, IUserActionType } from './store/reducers/user'
interface IProps {
user?: IUser,
changeName?(): void
}
class Example extends Component<IProps> {
handleChangeName = () => {
this.props.changeName && this.props.changeName()
}
render() {
return (
<div>
<div>{this.props.user?.name || '111'}</div>
<button onClick={this.handleChangeName}>ok</button>
</div>
)
}
}
const mapStateToProps = (state: rootState) => {
return {...state.user}
}
const mapDispatchToProps = (dispatch: Dispatch) => {
return {
changeName: () => {
dispatch({
type: IUserActionType.CHANGE,
payload: { user: { name: 'abcd' + Date.now()} }
})
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Example)
- 函数组件
import React from 'react'
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { rootState } from './store'
import { IUser, IUserActionType } from './store/reducers/user'
interface IProps {
user?: IUser,
changeName?(): void
}
const Example1: React.FC<IProps> = (props) => {
const handleChangeName = () => {
props.changeName && props.changeName()
}
return (
<div>
<div>{props.user?.name || '111'}</div>
<button onClick={handleChangeName}>ok</button>
</div>
)
}
const mapStateToProps = (state: rootState) => {
return {...state.user}
}
const mapDispatchToProps = (dispatch: Dispatch) => {
return {
changeName: () => {
dispatch({
type: IUserActionType.CHANGE,
payload: { user: { name: 'abcd' + Date.now()} }
})
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Example1)
- 函数组件+hooks
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { rootState } from './store'
import { IUserActionType } from './store/reducers/user'
const Example2: React.FC = () => {
const { user } = useSelector((state: rootState) => state.user)
const dispatch = useDispatch()
const handleChangeName = () => {
dispatch({
type: IUserActionType.CHANGE,
payload: { user: { name: 'abcd' + Date.now()} }
})
}
return (
<div>
<div>{user?.name || '111'}</div>
<button onClick={handleChangeName}>ok</button>
</div>
)
}
export default Example2