Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions playground\src\connected\connected-counter-with-decorator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// NOTE: Requires `"experimentalDecorators": true` in tsconfig.json
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { RootState } from '../store/types';
import { countersActions } from '../features/counters';

// Props passed by the parent component
interface OwnProps {
label: string;
}

// Props mapped from Redux state via mapStateToProps
interface StateProps {
count: number;
}

// Props mapped from Redux dispatch via mapDispatchToProps
interface DispatchProps {
onIncrement: () => void;
onDecrement: () => void;
}

// All props combined — used as the component Props type
type Props = OwnProps & StateProps & DispatchProps;

const mapStateToProps = (
state: RootState,
_ownProps: OwnProps
): StateProps => ({
count: state.counters.reduxCounter,
});

const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
bindActionCreators(
{
onIncrement: countersActions.increment,
onDecrement: countersActions.decrement,
},
dispatch
);

// Using @connect decorator
// Equivalent to:
// export default connect(mapStateToProps, mapDispatchToProps)(ConnectedCounterWithDecorator)
@connect<StateProps, DispatchProps, OwnProps, RootState>(
mapStateToProps,
mapDispatchToProps
)
class ConnectedCounterWithDecorator extends Component<Props> {
render() {
const { label, count, onIncrement, onDecrement } = this.props;

return (
<div>
<span>
{label}: {count}
</span>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
);
}
}

export default ConnectedCounterWithDecorator;
59 changes: 59 additions & 0 deletions playground\src\connected\connected-counter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { RootState } from '../store/types';
import { countersActions } from '../features/counters';
import { hotelsActions } from '../features/hotels';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The hotelsActions import is not used in this file and should be removed to maintain code cleanliness.


// Props that come from the parent component
interface OwnProps {
label: string;
}

// Props from Redux state (mapStateToProps)
interface StateProps {
count: number;
}

// Props from Redux dispatch (mapDispatchToProps)
interface DispatchProps {
onIncrement: () => void;
onDecrement: () => void;
}

// All component props combined
type Props = OwnProps & StateProps & DispatchProps;

// Map Redux state to component props
const mapStateToProps = (state: RootState, ownProps: OwnProps): StateProps => ({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The ownProps parameter is declared but never used within the mapStateToProps function. To improve code clarity and signal that this is intentional, it's best practice to prefix unused variables with an underscore.

Suggested change
const mapStateToProps = (state: RootState, ownProps: OwnProps): StateProps => ({
const mapStateToProps = (state: RootState, _ownProps: OwnProps): StateProps => ({

count: state.counters.reduxCounter,
});

// Map Redux dispatch to component props
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
bindActionCreators(
{
onIncrement: countersActions.increment,
onDecrement: countersActions.decrement,
},
dispatch
);

// Using the @connect decorator syntax
@connect(mapStateToProps, mapDispatchToProps)
class ConnectedCounter extends Component<Props> {
render() {
const { label, count, onIncrement, onDecrement } = this.props;
return (
<div>
<span>
{label}: {count}
</span>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
);
}
}

export default ConnectedCounter;
3 changes: 3 additions & 0 deletions playground\src\features\counters\index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { countersReducer } from './reducer';
export { countersActions } from './actions';
export { CounterState } from './types';
27 changes: 27 additions & 0 deletions playground\tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"experimentalDecorators": true,
"baseUrl": "."
},
"include": [
"src"
]
}