Reactjs + Flow:SyntheticKeyboardEvent并将函数作为props传递

时间:2018-04-28 21:18:26

标签: reactjs

我有以下AsyncApp.js组件

AsyncApp.js
// @flow
import React from "react";
import { connect } from "react-redux";
import _ from "lodash";
import { fetchPastLaunchesRequest } from "../actions/launches";
import { LaunchList } from "../components/launches/LaunchList";
import { Picker } from "../components/Picker";

type Props = {
  fetchPastLaunchesRequest: (launch_year: string) => Function,
  launches: Array<Object>,
  hasErrored: boolean,
  isLoading: boolean
};

class AsyncApp extends React.Component<Props, void> {
  componentDidMount() {
    let launch_year = "";
    this.props.fetchPastLaunchesRequest(launch_year);
  }

  handleOnChange = (e: SyntheticKeyboardEvent<HTMLInputElement>) => {
    this.props.fetchPastLaunchesRequest(e.currentTarget.value);
  };

  render() {
    const { launches, isLoading } = this.props;
    let launchYears = _.range(2005, 2019);
    return (
      <div id="launches">
        <Picker options={launchYears} onChange={this.handleOnChange} />
        {isLoading && launches.length === 0 && <h2>Loading...</h2>}
        {launches.length > 0 ? <LaunchList launches={launches} /> : <div />}
      </div>
    );
  }
}

const mapDispatchToProps = (dispatch: *) => {
  return {
    fetchPastLaunchesRequest: launch_year =>
      dispatch(fetchPastLaunchesRequest(launch_year))
  };
};

const mapStateToProps = state => {
  return {
    launches: state.launches.items,
    hasErrored: state.itemsHasErrored,
    isLoading: state.itemsIsLoading
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(AsyncApp);

Picker.js

//@flow

import React from "react";

type PickerProps = {
  options: Object,
  onChange: (e: HTMLInputElement) => void
};

export const Picker = ({ options, onChange }: PickerProps) => {
  return (
    <span>
      <select onChange={e => onChange(e)}>
        <option defaultValue=" ">Pick Year</option>
        {options.map(year => (
          <option value={year} key={year}>
            {year}
          </option>
        ))}
      </select>
    </span>
  );
};

我一直在AsyncApp.js组件中遇到此类型检查错误:

[flow] Cannot create `Picker` element because `SyntheticKeyboardEvent` [1] is incompatible with `HTMLSelectElement` [2] in the first argument of property `onChange`. (References: [1] [2])
(property) AsyncApp.handleOnChange: (e: any) => void
[Flow]
handleOnChange: (e: SyntheticKeyboardEvent < HTMLInputElement > ) => void

3 个答案:

答案 0 :(得分:1)

仅供记录。您还可以使用通配符:

onChange: (SyntheticEvent<*>) => void

onChange: (SyntheticInputEvent<*>) => void

答案 1 :(得分:1)

除了使用SyntheticEvent,我们还可以使用KeyboardEvent来识别按下的键盘键的类型。

const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {}

答案 2 :(得分:0)

将onChange的参数类型更改为 HTMLInputElement

//@flow

import React from "react";

type PickerProps = {
  options: Object,
  onChange: (e: HTMLInputElement) => void
};

export const Picker = ({ options, onChange }: PickerProps) => {
  return (
    <span>
      <select onChange={e => onChange(e)}>
        <option defaultValue=" ">Pick Year</option>
        {options.map(year => (
          <option value={year} key={year}>
            {year}
          </option>
        ))}
      </select>
    </span>
  );
};