React + TypeScript + Redux

一、下载Rudex
cnpm install -S redux react-redux @types/react-redux
src下建一个store文件
store下建action文件,action里面建个index.tsx
import {
      ADD_SHOP, DEL_SHOP } from '../constants';

//shop add
export interface ShopAddAction{
     
    obj: any;
    type: ADD_SHOP
}
export const addShop = (obj: any): ShopAddAction => ({
     
    obj,
    type: ADD_SHOP,
})

//shop del
export interface DelAddAction{
     
    key: number;
    type: DEL_SHOP
}
export const delShop = (key: number): DelAddAction => ({
     
    key,
    type: DEL_SHOP,
})

export type ShopAction = ShopAddAction | DelAddAction;

store下建constants文件,constants里面建个index.tsx
export const SET_VISIBILITY_FILTER = "SET_VISIBILITY_FILTER";
export type SET_VISIBILITY_FILTER = typeof SET_VISIBILITY_FILTER;

export const TOGGLE_TODO = "TOGGLE_TODO";
export type TOGGLE_TODO = typeof TOGGLE_TODO;

//添加
export const ADD_SHOP = "ADD_SHOP";
export type ADD_SHOP = typeof ADD_SHOP;
//删除
export const DEL_SHOP = "DEL_SHOP";
export type DEL_SHOP = typeof DEL_SHOP;
store下建reducers文件,reducers里面建个index.tsx
import {
      combineReducers } from 'redux';
import shops from './shop'

//这里的shops不是惟一的,可以引入多个以","隔开
export default combineReducers({
     
    shops
});
reducers里面建个shop.tsx

这个文件可以建多个,在store/index.tsx里引入

import {
      ShopAction } from '../actions/index';
import {
      ADD_SHOP, DEL_SHOP } from '../constants/index';
import {
      Shoping } from '../../types';

let list = [
    {
     
        name: "外国诗歌",
        price: 35,
        key: 1
    },
    {
     
        name: "文学理论",
        price: 99.19,
        key: 2
    },
    {
     
        name: "纪实文学",
        price: 41.61,
        key: 3
    },
    {
     
        name: "名家作品",
        price: 67.14,
        key: 4
    },
    {
     
        name: "外国随笔",
        price: 24.01,
        key: 5
    },
]
let indexKey = 5

const shops = (state: Shoping[] = list, action: ShopAction) => {
     
    switch (action.type) {
     
        case ADD_SHOP:
            indexKey ++
            return [...state, {
     ...action.obj, key: indexKey}];
        case DEL_SHOP:
            return state.filter((item: Shoping): boolean => {
     
                return action.key !== item.key
            })
        default:
            return state;
    }
}
  
export default shops;

src下建types文件,types里面建个index.tsx
export interface Shoping {
     
    name: string;
    price: number;
    key: number;
}
配置index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
// import * as serviceWorker from './serviceWorker';
import {
      Provider } from 'react-redux';
import {
      createStore } from 'redux';
import rootReducer from './store/reducers';
import registerServiceWorker from './registerServiceWorker';

const store = createStore(rootReducer);

ReactDOM.render(
  <Provider store={
      store }>
        <App />
    </Provider>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
registerServiceWorker();

组件内使用

connect方法是将store的数据或方法绑定到组件上的props上,这样props上就有了store里的数据

src/components/shop/shop.tsx

import * as React from 'react';
import './shop.css'
import {
      connect } from 'react-redux';
import {
      Dispatch } from 'redux';
import {
      delShop } from '../../store/actions/index'
import {
      Shoping } from '../../types';

//props
export interface IHomePageProps {
     
    shops?: any;
    onDel: (key: number) =>  void;
}
//state
export interface IHomePageState {
     

}

class Shop extends React.Component<IHomePageProps, IHomePageState> {
     
    constructor(props: IHomePageProps) {
     
        super(props);
        this.state = {
     
            
        };
    }

    componentDidMount = () => {
     
        console.log("props",this.props)
    }

    public click = (key: number): void => {
     
        let {
      onDel } = this.props
        onDel(key)
    }

    public render(){
     
        let {
      shops } = this.props
        return (
            <ul className="list">
                {
     
                    shops.map((item: Shoping) => {
     
                        return(
                            <li key={
     item.key}>
                                <p>{
      item.name }</p>
                                <p>${
      Number(item.price).toFixed(2) }</p>
                                <p onClick={
     () => {
     this.click(item.key)}}>删除</p>
                            </li>
                        )
                    })
                }
            </ul>
        )
    }
}

const shopStateToProps = (state: any): {
      shops: Shoping } => ({
     
    shops: state.shops
})

const shopDispatchToProps = (dispatch: Dispatch): {
      onDel: (key: number) => void } => ({
     
    onDel: (key: number) => dispatch(delShop(key)),
})

export default connect(shopStateToProps, shopDispatchToProps)(Shop);
title组件

src/components/title/title.tsx

import * as React from 'react';
import {
      connect } from 'react-redux';
import {
      Dispatch } from 'redux';
import {
      addShop } from '../../store/actions/index'

//props
export interface IHomePageProps {
     
    onAdd: (obj: any) => void
}
//state
export interface IHomePageState {
     
    name: string;
    price: string;
}

class Title extends React.Component<IHomePageProps, IHomePageState> {
     
    constructor(props: IHomePageProps) {
     
        super(props);
        this.state = {
     
            name: "this is a book",
            price: "999"
        };
    }

    componentDidMount = () => {
     
        
    }

    public change = (e: any, str: string): void => {
     
        (str === 'name')
        ? this.setState({
     name: e.target.value})
        : this.setState({
     price: e.target.value})
    }

    public add = (e: any): boolean | void => {
     
        if(e.keyCode === 13){
     
            let {
      name, price } = this.state
            let {
      onAdd } = this.props
            if(!name.trim() || !price.trim()){
     
                alert("请完善信息后再次尝试")
                return false
            }
            let obj = {
     
                name: name,
                price: price
            }
            onAdd(obj)
            this.setState({
     
                name: "",
                price: ""
            })
        }
    }

    public render(){
     
        let {
      name, price } = this.state
        return (
            <div>
                <input type="text" onChange={
     (e) => this.change(e,'name')} placeholder="name" value={
     name} />
                <input type="text" onKeyDown={
     (e) => this.add(e)} onChange={
     (e) => this.change(e,'price')} placeholder="price" value={
     price} />
            </div>
        )
    }
}

const titleStateToProps = (state: any) => ({
     
    
})

const titleDispatchToProps = (dispatch: Dispatch): {
      onAdd: (obj: any) => void } => ({
     
    onAdd: (obj: any) => dispatch(addShop(obj)),
})

export default connect(titleStateToProps,titleDispatchToProps)(Title);
效果


gitHub地址: https://github.com/z3116364593/rudex

你可能感兴趣的:(reactjs)