首页 > 解决方案 > 将 React Memo 与 Flow 一起使用的正确方法是什么?

问题描述

这行代码

export default memo(LoadingOverlay);

给出流量错误

Missing type annotation for `P`. `P` is a type parameter declared in  function type [1] and was implicitly instantiated at  call of `memo` [2].Flow(InferError)

而这条线

export default memo<TProps>(LoadingOverlay);

给出编译时错误。React memowith的正确用法是flow什么?

编辑:

这是完整的文件示例

// @flow

// React modules
import React, { memo } from 'react';

// Material UI components
import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';

// Utils and defaults
import './checkbox.scss';

type TProps = {
  value: string;
  label: string;
  checked: boolean;
  disabled?: boolean;
  onChange: Function;
};

/*
 * Presentational component with following props:
 *  value: String, value as a name of checkbox
 *  label: String, checkbox label
 *  checked: Boolean, checkbox state
 *  disabled: Boolean, checkbox availability state
 */
const Checkbox = (props: TProps) => {
  console.log('RENDER CHECKBOX');
  const {
    value,
    label,
    checked,
    disabled
  } = props;
  const { onChange } = props;

  return (
    <FormControlLabel
      control={
        <Checkbox
          checked={checked}
          onChange={onChange(value)}
          value={value}
          disabled={disabled}
          color="primary"
        />
      }
      label={label}
    />
  );
};

Checkbox.defaultProps = {
  disabled: false,
};

export default memo<TProps>(Checkbox);

标签: reactjsflowtype

解决方案


I have got the same problem. The problem is not with the Flow but with Babel.

React.memo with Flow

You have got it right. Correct approach really is:

export default memo<Props>(MyComponent);

Compilation problem

There are two ways to solve that.

1. Simple: Adding flow annotation to the top

Add // @flow to the top of the file. The error comes from Babel and it needs the annotation there. Even though you might have all=true in .flowconfig (and Flow work perfectly) you need to do that.

Useful when using create-react-app and do not want to eject.

2. Configuring Babel

Add Babel preset for Flow and specify "all": true option to your .babelrc:

{   
  "presets": [
    ["@babel/preset-flow", {
      "all": true
    }]
  ]
}

However, this needs anyone using create-react-app to eject. (Or might use react-app-rewired but I have no experience with that.)

This solution is mentioned on here (thanks @fl0shizzle for mentioning it) and for discussion about create-react-app solution look on here.


推荐阅读