TypeScript
React
material-ui
Formik

formik-material-ui の素振り

先日、 Typescript Deep Dive (日本語版) を読みました。react 経由で typescript に入ってきましたが、色々と追いついてなくてヤバイです。

それはそうと、formik + material-ui でググったら、material-ui をラップしたような formik-material-ui があったので、これを素振りしてみました。


素振り

今回は、HOC として Formik を食わせる withFormik でやりました。

基本的には、formikFieldcomponent に、

formik-material-ui のコンポーネントを渡してあげればよさそうでした。


Textfield

以下の画像の項目は TextField を渡すだけでできました。

text_fields.png

    <Field

name="text"
label="text *"
type="text"
component={TextField}
value={values.text}
onChange={handleChange}
fullWidth={true}
/>
<br />

<Field
name="email"
label="email *"
type="email"
component={TextField}
value={values.email}
onChange={handleChange}
fullWidth={true}
/>
<br />

<Field
name="password"
label="password *"
type="password"
component={TextField}
value={values.password}
onChange={handleChange}
error={errors.password && touched.password}
fullWidth={true}
/>
<br />

<Field
name="textarea"
label="textarea *"
type="text"
component={TextField}
value={values.textarea}
multiline={true}
fullWidth={true}
/>
<br />

<Field
name="select"
label="select *"
select={true}
component={TextField}
variant="outlined"
InputLabelProps={{ shrink: true }}
>
{['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((value, index) => (
<MenuItem key={index} value={value}>
{value}
</MenuItem>
))}
</Field>
<br />

<Field
name="date"
label="date *"
type="date"
InputLabelProps={{ shrink: true }}
component={TextField}
variant="outlined"
/>
<br />


ラジオ、チェックボックス系

radiogroup.png

    <Field

name="gender"
label="gender *"
component={RadioGroup}
values={values.gender}
onChange={handleChange}
>
<FormControlLabel
value="male"
label="Male"
control={<Radio disabled={isSubmitting} />}
disabled={isSubmitting}
/>
<FormControlLabel
value="female"
label="Female"
control={<Radio disabled={isSubmitting} />}
disabled={isSubmitting}
/>
<FormControlLabel
value="other"
label="Other"
control={<Radio disabled={isSubmitting} />}
disabled={isSubmitting}
/>
</Field>
<br />
<Field name="switch" label="switch" component={Switch} />
<br />
<Field name="checkbox" label="checkbox" component={Checkbox} />
<br />
<Field
name="checkboxwithlabel"
label="checkboxwithlabel"
component={CheckboxWithLabel}
Label={{ label: 'checkbox with label' }}
/>
<br />


ファイルアップロード系

プレビュー付きとかをやろうとすると、面倒なのことになるので、

そういうときは素直に Dropzone とかで片付けたほうがよさげです。

    <Field component={SimpleFileUpload} name="upload_file" />

<br />

<Field
name="file"
type="file"
onChange={(e: any) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (item: any) => {
setFieldValue('file_data', item.target.result);
};

reader.readAsDataURL(file);
}}
/>

<DropzoneArea
onChange={acceptedFiles => {
setFieldValue('files', acceptedFiles);
acceptedFiles.map((f: any, index: number) => {
const reader = new FileReader();
reader.onload = (item: any) => {
setFieldValue(`files_data${index}`, item.target.result);
};
reader.readAsDataURL(f);
});
}}
/>
<br />

files.png


参考にしたドキュメント等


コード

いろいろ試して遊んでいたので、汚い dispatch 等々が入ってます。

uitspitss/formik_mui_practice