cnpm install -S redux react-redux @types/react-redux
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;
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;
import {
combineReducers } from 'redux';
import shops from './shop'
//这里的shops不是惟一的,可以引入多个以","隔开
export default combineReducers({
shops
});
这个文件可以建多个,在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;
export interface Shoping {
name: string;
price: number;
key: number;
}
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);
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