使用打字稿将状态传递给react-redux中的子组件

时间:2018-08-03 08:18:09

标签: javascript reactjs typescript redux

也许我疯了,但是我想同时学习ReachJs,Redux和Typescript。主要是因为Visual Studio模板项目同时使用了这三个,而我也想学习这三个。

我真的很努力地掌握如何将状态从父组件传递到子组件。

在我的示例中,我有一个Counters组件,它只是想列出一些Counter组件。任何人都可以发表任何看法,或者我可以下载任何示例项目的任何示例,这些示例项目都包含react-redux和Typescript的全部三个-我正在努力寻找所有这三个示例。

我可以自己渲染一个计数器组件,但是一旦尝试使用父组件渲染多个计数器组件,我就会出错。

这是我的Counters.tsx

import * as React from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
import { ApplicationState }  from '../store';
import * as CountersStore from '../store/Counters';
import { Counter } from './Counter';

type CountersProps =
    CountersStore.CountersState
    & typeof CountersStore.actionCreators
    & RouteComponentProps<{}>;

class Counters extends React.Component<CountersProps, {}> {
    public render() {
        return <div className="m-2">
            {this.props.counters.map(x => <Counter props="x"/>)}
        </div>;
    }
}

// Wire up the React component to the Redux store
export default connect(
    (state: ApplicationState) => state.counters, // Selects which state properties are merged into the component's props
    CountersStore.actionCreators                 // Selects which action creators are merged into the component's props
)(Counters) as typeof Counters;

这是我的Counters.ts

import { Action, Reducer } from 'redux';
import * as Counter from './Counter';

export interface CountersState {
    counters: Counter.CounterState[]
}

interface DeleteCounterAction { type: 'DELETE_COUNTER', payload: number }
type KnownAction = DeleteCounterAction;

export const actionCreators = {
    increment: (valueCount: any) => <DeleteCounterAction>{ type: 'DELETE_COUNTER', payload: valueCount },
};

export const reducer: Reducer<CountersState> = (state: CountersState, incomingAction: Action) => {
    const action = incomingAction as DeleteCounterAction;
    switch (action.type) {
        case 'DELETE_COUNTER':
            return { counters: [] };
    }
    return state || { counters: [] };
};

这是我的Counter.tsx

import * as React from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
import { ApplicationState }  from '../store';
import * as CounterStore from '../store/Counter';

type CounterProps =
    CounterStore.CounterState
    & typeof CounterStore.actionCreators
    & RouteComponentProps<{}>;

export class Counter extends React.Component<CounterProps, {}> {
    public render() {
        return <div className="m-2">
            <span>{this.props.Text}</span>
            <span className={this.getBadgeClasses()}>{this.formatCount()}</span>
            <button className="btn btn btn-primary btn-sm m-2" onClick={() => { this.props.increment(2) }}>Increment</button>
            <button className="btn btn-danger btn-sm m-2" onClick={() => { this.props.increment(3) }}>Delete</button>
        </div>;
    }

    formatCount() {
        const currentCount = this.props.count;
        return currentCount === 0 ? "Zero" : currentCount;
    }

    getBadgeClasses() {
        let classes = "badge m-2 badge-";
        classes += this.props.count === 0 ? "warning" : "primary";
        return classes;
    }
}

// Wire up the React component to the Redux store
export default connect(
    (state: ApplicationState) => state.counter, // Selects which state properties are merged into the component's props
    CounterStore.actionCreators                 // Selects which action creators are merged into the component's props
)(Counter) as typeof Counter;

这是我的Counter.ts

import { Action, Reducer } from 'redux';

export interface CounterState {
    count: number;
    Text: string;
}

interface IncrementCountAction { type: 'INCREMENT_COUNT', payload: number }
interface DecrementCountAction { type: 'DECREMENT_COUNT', payload: number }

type KnownAction = IncrementCountAction | DecrementCountAction;

export const actionCreators = {
    increment: (valueCount: any) => <IncrementCountAction>{ type: 'INCREMENT_COUNT', payload: valueCount },
    decrement: (valueCount: any) => <DecrementCountAction>{ type: 'DECREMENT_COUNT', payload: valueCount },
};

export const reducer: Reducer<CounterState> = (state: CounterState, incomingAction: Action) => {
    const action = incomingAction as KnownAction;
    switch (action.type) {
        case 'INCREMENT_COUNT':
            return { count: state.count + action.payload, Text: state.Text + action.payload.toString() };
        case 'DECREMENT_COUNT':
            return { count: state.count - action.payload, Text: state.Text  };
        default:
            const exhaustiveCheck: never = action;
    }

    return state || { count: 0, Text: "Hello" };
};

0 个答案:

没有答案