React-Redux Connect组件无ownProps时Flow报错:props与空值不兼容
Let’s tackle this Flow error head-on. The core issue here is that Flow isn’t correctly recognizing that react-redux’s connect is injecting all the props your Credits component needs. It’s mistakenly thinking you’re missing required props when you render <Credits /> without passing anything directly. Here’s how to fix it step by step:
Step 1: Explicitly Define Prop Types and Connect Generics
Flow relies on clear type definitions to understand how connect maps Redux state/dispatch to your component’s props. You’ll want to explicitly define four key types:
- The full set of props your
Creditscomponent uses - The props returned by
mapStateToProps - The props returned by
mapDispatchToProps - The "own props" (an empty object
{}here, since you don’t pass any props directly to<Credits />)
Here’s a concrete example:
// src/components/Credits.js import { connect } from 'react-redux'; import type { State } from '../store'; // Import your root Redux state type // Define all props your component expects type CreditsProps = { // Props pulled from Redux state userCredits: number, // Props mapped to Redux dispatch actions refreshCredits: () => void, }; // Your component, typed with CreditsProps const Credits = ({ userCredits, refreshCredits }: CreditsProps) => ( <div> <p>Your credits: {userCredits}</p> <button onClick={refreshCredits}>Refresh Balance</button> </div> ); // Define props coming from Redux state type StateProps = { userCredits: number, }; const mapStateToProps = (state: State): StateProps => ({ userCredits: state.user.credits, }); // Define props mapped to dispatch actions type DispatchProps = { refreshCredits: () => void, }; const mapDispatchToProps = (dispatch): DispatchProps => ({ refreshCredits: () => dispatch({ type: 'REFRESH_CREDITS' }), }); // Explicitly pass generics to connect: StateProps, DispatchProps, OwnProps export default connect<StateProps, DispatchProps, {}>( mapStateToProps, mapDispatchToProps )(Credits);
Step 2: Handle Shorthand mapDispatchToProps (If You Use It)
If you prefer the shorthand syntax for mapDispatchToProps (passing an object of action creators directly), use typeof to let Flow infer the dispatch props type automatically—no need to repeat definitions:
import { refreshCredits } from '../actions/credits'; // Import your action creator const mapDispatchToProps = { refreshCredits }; // Use typeof to infer DispatchProps export default connect<StateProps, typeof mapDispatchToProps, {}>( mapStateToProps, mapDispatchToProps )(Credits);
Step 3: Double-Check for Unmatched Props
Make sure every prop your Credits component references is either defined in StateProps or DispatchProps. If your component uses a prop that isn’t provided by mapState or mapDispatch, Flow might throw an error that manifests as this "incompatible with empty" message.
Why This Works
By explicitly defining the generic types for connect, you’re telling Flow exactly how props are supplied to your component:
- "This component gets
StatePropsfrom the Redux state" - "This component gets
DispatchPropsfrom Redux dispatch" - "This component doesn’t accept any direct props (hence
{})"
This eliminates the confusion that causes Flow to incorrectly flag your <Credits /> render as missing props.
内容的提问来源于stack exchange,提问作者Francisco Sarmento




