I tried Redux's Tutorial with TypeScript. (n-changing)
I'll write down my own best practices for now.
$ create-react-app < App名> --scripts-version=react-scripts-ts # TypeScriptで作成.
$ yarn add redux react-redux # reduxを追加
$ yarn add -D @types/react-redux tslint-config-airbnb # reduxのtypeと、air-bnbのtslintを追加. To control ourselves, we have introduced tslint-config-airbnb .
Global
"globals" : {
"window" : true ,
"location" : true ,
"document" : true
},It's good to write something like that.
For more details, see tslint.json .
Actions are implemented in reference to Flux Standard Action and values are stored within payload .
The interface extends the action of Redux.
interface AddTodoAction extends Action {
type: ActionTypes . ADD_TODO ;
payload: {
id: number ;
text: string ;
} ;
}Additionally, by defining ActionType as enum, it provides a safer implementation.
export enum ActionTypes {
ADD_TODO = 'ADD_TODO' ,
SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER' ,
TOGGLE_TODO = 'TOGGLE_TODO' ,
}To specify the type of the action argument in Reducer, it is a good idea to export the type as a shared type called TodoActions.
export type TodoActions = AddTodoAction | SetVisibilityFilterAction | ToggleTodoAction ; State is an interface defined in states/ . Each state takes over Redux's ideas and is specified as readonly.
By defining Object State, you can use types in various places, making it convenient.
export interface TodoState {
readonly id : number ;
readonly text : string ;
readonly completed : boolean ;
}Additionally, by defining the state of the root stored in the store with an interface, you can write the inside of the state document in a document.
export interface State {
readonly visibilityFilter : VisibilityFilters ;
readonly todos : TodoState [ ] ;
} You should just implement it honestly.
Since it is a Presentational component, it is basically implemented to be SFC.
The argument props were written in Tutorial as ({ active, children, onClick }) , but using this as a reference, props are expanded within the function.
What you do remains the same, so you can decide based on your preference. Personally, if you write it as an argument, the variable definition section becomes too redundant, so you prefer the inside of the function.
Each component's props defines an interface as OwnProps.
export interface OwnProps {
active: boolean ;
onClick: ( ) => any ;
}
const Link : React . SFC < OwnProps > = (props) = > {
const { children , active , onClick } = props;
return (
< button
onClick = { onClick }
disabled = { active }
style = { {
marginLeft : '4px' ,
} }
>
{ children }
</ button >
);
} ;
export default Link ;I think SFC is fine for the app directly under Provider.
const App : React . SFC = ( ) => (
< div >
< AddTodo />
< VisibleTodoList />
< Footer />
</ div >
) ;
export default App ; It seems like it's overkill, but we define DispatchToProps interface as the return values of mapStateToProps , as StateToProp interface and mapDispatchToProps .
interface StateToProps {
todos: TodoState [ ] ;
}
interface DispatchToProps {
toggleTodo: ( id : number ) => any ;
} When AddTodo in Tutorial connect()(AddTodo) , the type of AddTodo becomes vague, so it's a good idea to export the one connect()(AddTodo) as is.
2018.4.13