也许我疯了,但是我想同时学习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" };
};