formik-material-ui 不适用于 TogglleButtonGroup 组件
Posted
技术标签:
【中文标题】formik-material-ui 不适用于 TogglleButtonGroup 组件【英文标题】:formik-material-ui not working for TogglleButtonGroup Component 【发布时间】:2020-09-29 23:24:11 【问题描述】:在我的 React 代码中,连同其他输入类型,我还必须使用 material-ui 的 ToggleButtonGroup 组件。 formik-material-ui 不直接支持该组件,我一直在尝试编写自定义包装器,但没有取得多大成功。这就是我的组件的外观(formikToggleButtonGroup.tsx):
import * as React from 'react';
import MuiToggleButtonGroup,
ToggleButtonGroupProps as MuiToggleButtonGroupProps,
from '@material-ui/lab/ToggleButtonGroup';
import FieldProps from 'formik';
export interface ToggleButtonGroupProps
extends FieldProps,
Omit<MuiToggleButtonGroupProps, 'name' | 'value'>
export function fieldToToggleButtonGroup(
field,
// Exclude Form
form,
...props
: ToggleButtonGroupProps): MuiToggleButtonGroupProps
return
...props,
...field,
;
export default function ToggleButtonGroup(props: ToggleButtonGroupProps)
return <MuiToggleButtonGroup ...fieldToToggleButtonGroup(props) />;
ToggleButtonGroup.displayName = 'FormikMaterialUIToggleButtonGroup';`
然后,我尝试像这样使用它:
import Layout from '../../components/layout'
import Header from '../../components/header'
import ToggleButtonGroup from '../../components/formikToggleButtonGroup.tsx'
import React, useState from 'react';
import makeStyles from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Container from '@material-ui/core/Container';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Box from '@material-ui/core/Box';
import ToggleButton from '@material-ui/lab/ToggleButton';
import withStyles from '@material-ui/core/styles';
import green, orange from '@material-ui/core/colors';
import Radio from '@material-ui/core/Radio';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
import * as Yup from "yup";
import Formik, Form, Field from 'formik';
import TextField, RadioGroup from 'formik-material-ui';
import ToggleButtonGroup from '../../components/formikToggleButtonGroup.tsx'
import ToggleButton from '@material-ui/lab/ToggleButton';
const StyledButton = withStyles((theme)=>(
root:
background: theme.palette.background.paper,
color: theme.palette.text.primary,
marginBottom: theme.spacing(3),
marginRight: theme.spacing(4),
borderRadius: '0',
borderWidth: '1px',
borderColor: theme.palette.divider,
borderLeft:'1px solid rgba(0, 0, 0, 0.12) !important',
padding: '0 30px',
fontSize:'0.7rem',
fontWeight:'400',
'&$selected':
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.main,
,
'&:hover':
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
,
'&$selected:hover':
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
,
,
selected:
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.main,
,
hover:
color: theme.palette.background.default,
backgroundColor: theme.palette.warning.light,
,
label:
textTransform: 'capitalize',
,
))(ToggleButton);
export default function GetUserInfo()
const classes = useStyles();
const [selectedValue, setSelectedValue] = useState('yes');
const handleRadioChange = (event) =>
setSelectedValue(event.target.value);
;
const handleSubmit = (evt) =>
evt.preventDefault();
alert(`Submitting Name $name $phone $email`)
const handleChange = (event, newAlignment) =>
alert(newAlignment)
if (newAlignment !== null)
setGrade(newAlignment);
;
return (
<Layout title="My first Next page" meta_desc="Best online coding classes for kids & children">
<CssBaseline />
<Header />
<Container component="main" >
<Grid container spacing=4>
<Grid item xs=12 sm=8 className=classes.boxStyle>
<Box mx="auto" p=2>
<Formik
initialValues=initialValues
validate=
values =>
const errors = ;
if (!values.parentEmail)
errors.parentEmail = 'Required';
else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]2,4$/i.test(values.parentEmail)
)
errors.parentEmail = 'Invalid email address';
else if (!values.parentName)
errors.parentName = 'Required';
else if (!values.countryCode)
errors.countryCode = 'Required';
else if (!values.phone)
errors.phone = 'Required';
else if (!values.childName)
errors.childName = 'Required';
else if (!values.grade)
errors.grade = 'Required';
else if (!values.computer)
errors.computer = 'Required';
return errors;
onSubmit=(values, setSubmitting ) =>
setTimeout(() =>
setSubmitting(false);
alert(JSON.stringify(values, null, 2));
, 500);
>
( submitForm, isSubmitting ) => (
<Form className=classes.root autoComplete="off">
<Box>
<Field
component=TextField
fullWidth
name="childName"
onChange=e => setChildName(e.target.value)
required id="standard-required" label="Kid's Name"
helperText="Certificate will be issued with this name"/>
</Box>
<Box mt=3 className=classes.labelFont>
Kid's Grade?
</Box>
<Box mt=2>
<ToggleButtonGroup
component=ToggleButtonGroup
mt=7
name="grade"
//value=grade
exclusive="true"
//onChange=handleChange
aria-label="text alignment"
>
<StyledButton className=classes.buttonMargin
value="1" aria-label="left aligned">
<label class="btn btn-secondary m-2 rounded">
Grade <br/> <strong>1 - 3</strong>
</label>
</StyledButton>
<StyledButton className=classes.buttonMargin value="2" aria-label="centered">
<label class="btn btn-secondary m-2 rounded ">
Grade <br/> <strong>4 - 6</strong>
</label>
</StyledButton>
<StyledButton className=classes.buttonMargin value="3" aria-label="right aligned">
<label class="btn btn-secondary m-2 rounded">
Grade <br/> <strong>7 - 9</strong>
</label>
</StyledButton>
<StyledButton className=classes.buttonMargin value="4" aria-label="justified">
<label class="btn btn-secondary m-2 rounded">
Grade <br/><strong>10 - 12</strong>
</label>
</StyledButton>
</ToggleButtonGroup>
</Box>
<Button
disabled=isSubmitting
onClick=submitForm
//type="submit"
//onClick=handleSubmit
fullWidth
variant="contained"
color="primary"
className=classes.submit>Let's Start
</Button>
</Form>
)
</Formik>
</Box>
</Grid>
</Grid>
</Container>
</Layout>
)
我面临的问题是 Formik 没有设置 ToggleButtonGroup 的值。它总是显示初始值。
【问题讨论】:
【参考方案1】:通过手动处理 onChange
事件并手动更新 formik 实例,我能够使 formik 与 ToggleButtonGroup
一起工作:
export default function MyComponent()
const formik = useFormik(
initialValues:
roleType: 0,
,
onSubmit: async (values) =>
// send ajax request
,
);
// handler for ToggleButtonGroup
const handleRoleChange = (event: any, role: string) =>
// manually update formik
formik.setFieldValue('roleType', role);
;
return (
<form noValidate onSubmit=formik.handleSubmit>
<ToggleButtonGroup
exclusive
id="roleType"
value=formik.values.roleType
onChange=handleRoleChange
>
<ToggleButton value=0>
<PersonIcon />
<div>Role 1</div>
</ToggleButton>
<ToggleButton value=1>
<RestaurantIcon />
<div>Role 2</div>
</ToggleButton>
</ToggleButtonGroup>
<Button type="submit">
Submit
</Button>
</form>
);
【讨论】:
以上是关于formik-material-ui 不适用于 TogglleButtonGroup 组件的主要内容,如果未能解决你的问题,请参考以下文章
AS 兼容性:“.. from T as a..”适用于 MySQL 和 SQL Server,而不适用于 Oracle? [复制]