使用redux-form
和flow
获得了此组件。
// @flow
import * as React from 'react';
import Button from '@material-ui/core/Button';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import Paper from '@material-ui/core/Paper';
import { withNamespaces } from 'react-i18next';
import { Link } from 'react-router-dom';
import {
connect,
} from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import useStyles from './styles';
import {
login,
} from '../../redux/index';
const logo = './assets/images/logo.png';
type TInputProps = {
input: Object,
meta: {
submitting: boolean,
}
}
const UserNameInput = (props: TInputProps) => (
<Input
id="email"
name="email"
autoComplete="email"
autoFocus
{...props}
{...props.input}
disabled={props.meta.submitting}
/>
);
const PasswordInput = (props: TInputProps) => (
<Input
name="password"
type="password"
id="password"
autoComplete="current-password"
{...props}
{...props.input}
disabled={props.meta.submitting}
/>
);
type TProps = {
t: Function,
login: Function,
handleSubmit: Function,
error: string,
submitting: boolean,
}
const Login = ({
t,
login,
handleSubmit,
error,
submitting,
}: TProps) => {
const classes = useStyles();
return (
<main className={classes.main}>
<Paper className={classes.paper}>
<img src={logo} alt="logo" className={classes.logo} />
<form
className={classes.form}
onSubmit={handleSubmit((values) => {
// return here is very important
// login returns a promise
// so redux-form knows if it is in submission or finished
// also important to return because
// when throwing submissionErrors
// redux-form can handle it correctly
return login(values);
})}
>
<FormControl margin="normal" required fullWidth>
<Field
name="email"
type="text"
component={UserNameInput}
label={<InputLabel htmlFor="email">{t('Username')}</InputLabel>}
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<Field
name="password"
type="password"
component={PasswordInput}
label={
<InputLabel htmlFor="password">{t('Password')}</InputLabel>
}
/>
</FormControl>
<div className={classes.error}>{error}</div>
<Button
disabled={submitting}
type="submit"
fullWidth
variant="outlined"
color="primary"
className={classes.submit}
>
{t('Sign in')}
</Button>
<Link className={classes.forgot} to="/forgot">
{t('Forgot Password?')}
</Link>
</form>
</Paper>
</main>
);
};
export default connect(
null,
{
login,
}
)(
reduxForm({ form: 'login' })(withNamespaces()(Login))
);
在<Field />
或component={PasswordInput}
所在的component={UserNameInput}
内
flow
出现以下错误
Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/features/Auth/components/Login/index.js:95:26
Could not decide which case to select. Since case 1 [1] may work but if it doesn't case 2 [2] looks promising too. To
fix add a type annotation to return [3].
src/features/Auth/components/Login/index.js
[3] 39│ <Input
40│ name="password"
41│ type="password"
42│ id="password"
43│ autoComplete="current-password"
44│ {...props}
45│ {...props.input}
46│ disabled={props.meta.submitting}
47│ />
:
92│ <Field
93│ name="password"
94│ type="password"
95│ component={PasswordInput}
96│ label={
97│ <InputLabel htmlFor="password">{t('Password')}</InputLabel>
98│ }
node_modules/redux-form/lib/FieldProps.types.js.flow
[1][2] 8│ component: ComponentType<*> | Function | string,