react+redux+ts
阿新 • • 發佈:2021-11-18
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