收集至:https://zhuanlan.zhihu.com/p/42141179
无状态组件
import * as React from "react";const TestPage: React.SFC = () => {return (<div>this is test page.</div>);};export default TestPage;
当我们需要传递 Props 时,只用定义一个 Props 接口,然后给 props 指明类型:
export interface IHeaderProps {localImageSrc: string;onLineImageSrc: string;}export const Header: React.SFC<IHeaderProps> = (props: IHeaderProps) => {const { localImageSrc, onLineImageSrc } = props;return (<div className={styles["header-container"]}><img src={localImageSrc} /><img src={onLineImageSrc} /></div>);};
有状态组件
export interface IHomePageState {name: string;}class HomeComponent extends React.Component<{}, IHomePageState> {constructor(props: {}) {super(props);this.state = {name: "",};}public setName = () => {this.setState({name: "icepy",});}public render(){const { name } = this.state;return (<div><div onClick={this.setName}> set name </div><div>{name}</div></div>)}}
Props & State 组件
export interface IHomePageState {name: string;}export interface IHomePageProps {home: string;}class HomeComponent extends React.Component<IHomePageProps, IHomePageState> {constructor(props: IHomePageProps) {super(props);this.state = {name: "",};}public setName = () => {this.setState({name: "icepy",});}public render(){const { name } = this.state;const { home } = this.props;return (<div><div onClick={this.setName}> set name </div><div>{name} {home}</div></div>)}}
Router 组件
import { RouteComponentProps } from "react-router-dom";export interface IHomePageProps extends RouteComponentProps<any>{home: string;}export interface IHomePageState {home: string;}class HomeComponent extends React.Component<IHomePageProps, IHomePageState> {constructor(props: IHomePageProps) {super(props);this.state = {name: "",};}public setName = () => {this.setState({name: "icepy",});}public render(){const { name } = this.state;const { home } = this.props;return (<div><div onClick={this.setName}> set name </div><div>{name} {home}</div></div>)}}
页面级别的 Reducers
为类型安全定义接口:
import { Dispatch } from "redux";import { RouteComponentProps } from "react-router-dom";export interface IHomePageActionsProps {dataSync: () => void;dataAsync: (parameter: string) => (dispatch: Dispatch) => void;}export interface IHomePageProps extends RouteComponentProps<any>, IHomePageActionsProps {homePage: IHomePageStoreState;}export interface IHomePageStoreState {syncId: string;asyncId: string;}// global direxport interface IStoreState {homePage: IHomePageStoreState;}
定义一个 mapStateToProps 函数:
const mapStateToProps = (state: IStoreState) => {const { homePage } = state;return {homePage,};};
定义 Action 和 Reducers:
// actionimport * as CONST from "./constants";import { Dispatch } from "redux";export function dataSync() {const syncData = {type: CONST.SYNC_DATA,payload: {data: "syncId=https://github.com/icepy",},};return syncData;}export function dataAsync(parameter: string): (dispatch: Dispatch) => void {return (dispatch: Dispatch) => {const asyncData = {type: CONST.ASYNC_DATA,payload: {data: "asyncId=https://icepy.me",},};setTimeout(() => {dispatch(asyncData);}, 2000);};}// reducersimport { IAction } from "@/global/types";import * as CONST from "./constants";import * as TYPES from "./types";const initState: TYPES.IHomePageStoreState = {syncId: "默认值",asyncId: "默认值",};export function homeReducers(state = initState, action: IAction): TYPES.IHomePageStoreState {const { type, payload } = action;switch (type) {case CONST.SYNC_DATA:return { ...state, syncId: payload.data };case CONST.ASYNC_DATA:return { ...state, asyncId: payload.data };default:return { ...state };}}
在 Store 中 引入我们的 reducers:
import { createStore, applyMiddleware, combineReducers, compose } from "redux";import thunk from "redux-thunk";import { homeReducers } from "@/pages/Home/flow/homeReducers";/* eslint-disable no-underscore-dangle, no-undef */const composeEnhancers = (window as any) && (window as any).REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose;const reducer = combineReducers({homePage: homeReducers,});export const configureStore = () => createStore(reducer,composeEnhancers(applyMiddleware(thunk)),);
使用 connect 函数将这些关联起来:
class HomeComponent extends React.Component<TYPES.IHomePageProps, TYPES.IHomePageState> {... 省略}export const HomePage = connect(mapStateToProps, actions)(HomeComponent);
Global级别的 Reducers
global 顾名思义,这是一种可以全局访问的 reducers ,我们要做的事情也和页面级别 reducers 非常类似,定义好 state 的接口,然后将 global 在 Store 中配置正确,如:
import { createStore, applyMiddleware, combineReducers, compose } from "redux";import thunk from "redux-thunk";import { homeReducers } from "@/pages/Home/flow/homeReducers";import { globalReducers } from "./reducers";const composeEnhancers = (window as any) && (window as any).REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose;const reducer = combineReducers({global: globalReducers,homePage: homeReducers,});export const configureStore = () => createStore(reducer,composeEnhancers(applyMiddleware(thunk)),);
当我们需要访问 global 时,有两种方式:
在 mapStateToProps 函数中将 global 返回给页面级别的 Props
随意的调用 global 中的 Action ,只是需要手动的将 dispatch 函数传递给这些 Action
import * as React from "react";import { Dispatch } from "redux";import { connect } from "react-redux";import { HashRouter as Router, Route, NavLink } from "react-router-dom";import { IStoreState } from "./global/types";import * as globalActions from "./global/actions";import { HomePage } from "./pages/Home";import { TestPage } from "./pages/TestPage";import "./style.less";interface IAppComponentProps {dispatch: Dispatch;}class AppComponent extends React.Component<IAppComponentProps> {constructor(props: IAppComponentProps) {super(props);globalActions.setGlobalSyncId(this.props.dispatch);}public render() {return (<Router ><div><div className="nav-container"><NavLink to="/" >Home Page</NavLink><NavLink to="/test">Test Page</NavLink></div><Route exact={true} path="/" component={HomePage} /><Route path="/test" component={TestPage} /></div></Router>);}}const mapStateToProps = (state: IStoreState) => {const { global } = state;return {global,};};export const App = connect(mapStateToProps)(AppComponent);
