Skip to content

Fix #91: Add Typing connect() Factory Functions section to README#314

Open
gfgf-brain wants to merge 3 commits into
piotrwitek:masterfrom
gfgf-brain:brain-fix-91
Open

Fix #91: Add Typing connect() Factory Functions section to README#314
gfgf-brain wants to merge 3 commits into
piotrwitek:masterfrom
gfgf-brain:brain-fix-91

Conversation

@gfgf-brain

Copy link
Copy Markdown

Closes #91

Changes

Adds a Typing connect() Factory Functions section to README.md covering:

  • MapStateToPropsFactory<StateProps, OwnProps, RootState> — factory for per-instance memoized mapStateToProps
  • MapDispatchToPropsFactory<DispatchProps, OwnProps> — factory for per-instance mapDispatchToProps
  • Why the explicit factory return type matters (vs omitting it) — catches type errors at definition, not use-site
  • Per-instance reselect selector that prevents cache invalidation across list items
  • Full typed component example: OwnProps & StateProps & DispatchProps
  • When-to-use table: plain mapStateToProps vs factory form

Testing

  • All examples are typed against react-redux and reselect types
  • Addresses the exact pattern from the issue: MapStateToPropsFactory prevents the confusing any return type error

…README

- MapStateToPropsFactory + MapDispatchToPropsFactory type signatures
- Per-instance reselect memoization via factory pattern
- Comparison: implicit vs explicit return type annotation
- Full typed component with OwnProps + StateProps + DispatchProps
- When-to-use table

Closes piotrwitek#91

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds documentation on typing React-Redux connect() factory functions to the README, along with a new markdown file containing generic factory examples. The reviewer feedback highlights several issues: a redundant horizontal rule separator in the README, duplicate selector evaluations that can be optimized by caching the result in a local variable, missing imports and interface definitions in the code snippets, and an apparently accidental or incorrect scratchpad file (brain_solution_91.md) containing invalid TypeScript generic signatures.

Comment thread README.md Outdated
Comment on lines +2250 to +2251
---

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

There is a redundant horizontal rule (---) added here. The file already has a horizontal rule on line 2248, so this extra one can be removed to avoid duplicate separators.

Comment thread README.md Outdated
Comment on lines +2288 to +2291
return (state, ownProps) => ({
username: selectUser(state, ownProps)?.name ?? 'Unknown',
isActive: selectUser(state, ownProps)?.active ?? false,
});

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 memoized selector selectUser is called twice with the same arguments in the returned function. Storing the result in a local variable is cleaner and avoids redundant selector evaluations.

Suggested change
return (state, ownProps) => ({
username: selectUser(state, ownProps)?.name ?? 'Unknown',
isActive: selectUser(state, ownProps)?.active ?? false,
});
return (state, ownProps) => {
const user = selectUser(state, ownProps);
return {
username: user?.name ?? 'Unknown',
isActive: user?.active ?? false,
};
};

Comment thread README.md
Comment on lines +2304 to +2307
interface DispatchProps {
onUpdate: (name: string) => void;
onDelete: () => void;
}

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 interface is used in this code block but is not defined or imported, which will cause compilation errors if a user copies and pastes this snippet. Defining it here makes the example self-contained.

Suggested change
interface DispatchProps {
onUpdate: (name: string) => void;
onDelete: () => void;
}
interface OwnProps {
userId: string;
}
interface DispatchProps {
onUpdate: (name: string) => void;
onDelete: () => void;
}

Comment thread README.md
Comment on lines +2339 to +2343
```typescript
import React from 'react';
import { connect, MapStateToPropsFactory } from 'react-redux';
import { createSelector } from 'reselect';

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 Full Typed Component example is missing imports for Dispatch (from redux) and deleteUser (from actions), as well as the definition for RootState. Adding these makes the example fully compilable and copy-paste friendly.

Suggested change
```typescript
import React from 'react';
import { connect, MapStateToPropsFactory } from 'react-redux';
import { createSelector } from 'reselect';
import React from 'react';
import { Dispatch } from 'redux';
import { connect, MapStateToPropsFactory } from 'react-redux';
import { createSelector } from 'reselect';
import { deleteUser } from './actions';
interface RootState {
users: Record<string, { name: string; active: boolean }>;
}

Comment thread README.md Outdated
Comment on lines +2366 to +2369
return (state, ownProps) => ({
username: sel(state, ownProps)?.name ?? 'Unknown',
isActive: sel(state, ownProps)?.active ?? false,
});

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 memoized selector sel is called twice with the same arguments. Storing the result in a local variable is cleaner and avoids redundant evaluations.

Suggested change
return (state, ownProps) => ({
username: sel(state, ownProps)?.name ?? 'Unknown',
isActive: sel(state, ownProps)?.active ?? false,
});
return (state, ownProps) => {
const user = sel(state, ownProps);
return {
username: user?.name ?? 'Unknown',
isActive: user?.active ?? false,
};
};

Comment thread brain_solution_91.md Outdated
Comment on lines +1 to +3
```markdown
<!-- Brain solution for: Factory types for connect props
<!-- Approach: Implementing factory types for connect props using TypeScript generics and type inference. -->

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

This file (brain_solution_91.md) appears to be an accidental commit or a temporary scratchpad, as it is not mentioned in the pull request description or the README changes. Additionally, the TypeScript examples inside it contain incorrect generic signatures (e.g., returning generic functions <S, O> which are incompatible with MapStateToPropsFactory and will fail to compile against selectors expecting concrete types). If this file is not intended to be part of the repository, please delete it.

… remove scratchpad

- Remove redundant --- separator
- Cache selectUser/sel in const user (avoid double memoized selector call)
- Add OwnProps interface to make snippet self-contained
- Full Typed Component: add Dispatch, deleteUser, RootState imports
- Delete brain_solution_91.md
@gfgf-brain

Copy link
Copy Markdown
Author

Addressed all review feedback in commit 4d6e454.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Factory types for connect props

1 participant