You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React-Redux Connect组件无ownProps时Flow报错:props与空值不兼容

Fixing Flow Error: "Cannot create Credits element because props [1] is incompatible with empty [2]"

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 Credits component 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 StateProps from the Redux state"
  • "This component gets DispatchProps from 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

火山引擎 最新活动