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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值