I am trying to use this boilerplate for my react typescript project. I am unable to configure right type of actions. It was easy with JavaScript. But I am new to TypeScript. I want to know why my code is not working. Also please suggest the best way to solve this problem.
Dashboard.tsx
interface IAction{
type: string,
payload: any,
}
interface IProps {
// dashboard: DashboardState;
dashboard: any;
// Actions
changeUserName: IAction;
}
interface IState {}
class Dashboard extends React.Component<IProps, IState> {
componentDidMount(){
console.log("____FOCUS____");
console.log(this.props);
this.props.changeUserName("NewName");
console.log("____FOCUS____");
// this.props.changeUserName('New Name');
}
render() {
return (
<>
<Helmet>
<title>Dashboard</title>
<meta name="description" content="Description of Dashboard" />
</Helmet>
<DashboardComponent username={'somevalue'} />
{/* <Div>{t('')}</Div> */}
</>
);
}
}
const mapStateToProps = (state: any, ownProps: any) => ({
dashbaord: selectDashboard(state),
});
const mapDispatchToProps = (dispatch: any, ownProps: any) => ({
...bindActionCreators({
...actions,
}, dispatch),
});
const withConnect = connect(mapStateToProps, mapDispatchToProps);
const withReducer = injectReducer({key: sliceKey, reducer: dashboardReducer});
const withSaga = injectSaga({key: sliceKey, saga: dashboardSaga});
export default compose(
withReducer,
withConnect,
withSaga,
)(Dashboard);
Types
Types that I am creating are also as in docs.
/* --- STATE --- */
export interface DashboardState {
username: string;
}
export type ContainerState = DashboardState;
Slice
This is the slice I am creating. It is as described in docs.
export const initialState: ContainerState = {
username: 'Initial Username',
};
const dashboardSlice = createSlice({
name: 'dashboard',
initialState,
reducers: {
changeUserName(state, action: PayloadAction<string>) {
state.username = action.payload;
},
},
});
export const { actions, reducer, name: sliceKey } = dashboardSlice;
Problem
I was no creating interfaces the right way. The method of dispatching class based components was same as before. Only problem was interfaces that are now right.
Solution Code
Dashboard.tsx
interface IProps {
initChangeUserName: Function;
changeUserName: Function;
}
interface IState {}
class Dashboard extends React.Component<IProps, IState> {
render() {
return (
<>
<Helmet>
<title>Dashboard</title>
<meta name="description" content="Description of Dashboard" />
</Helmet>
<DashboardComponent
username={'somevalue'}
initChangeUserName={this.props.initChangeUserName}
/>
</>
);
}
}
const mapStateToProps = (state: any, ownProps: any) => ({
dashboard: selectDashboard(state),
});
const mapDispatchToProps = (dispatch: any, ownProps: any) => ({
...bindActionCreators({ ...actions }, dispatch),
});
const withConnect = connect(mapStateToProps, mapDispatchToProps);
const withReducer = injectReducer({ key: sliceKey, reducer: dashboardReducer });
const withSaga = injectSaga({ key: sliceKey, saga: dashboardSaga });
export default compose(
withReducer,
withConnect,
withSaga,
)(Dashboard);
DashboardComponent.tsx
// ....
// This was a functional component
<UserNameForm initChangeUserName={props.initChangeUserName} />
// ....
UserNameForm.tsx
// ....
this.props.initChangeUserName(this.state.username);
// ....