#javascript #reactjs #formik
#javascript #reactjs #formik
Вопрос:
У меня есть эти состояния в моем компоненте.
const [initialValues, setInitialValues] = useState({
name: "",
name2: "",
items: []
});
name
и name2
объединил вместе и создал массив {name: 'sss', name2: 'sss'}
и отправил в items
массив. Нажимная часть в порядке. Единственная проблема заключается в том, кто должен удалить элемент из этого массива.
Это мой код https://codesandbox.io/s/material-demo-forked-u2qzv?file=/demo.js:260-362
Обычные методы массива, похоже, здесь не работают.
Как мне исправить React и Formik?
Комментарии:
1. Я думаю, что с вашим текущим подходом вы столкнетесь с большим количеством проблем в будущем. Проверьте мой ответ; вы можете настроить его, чтобы получить пользовательский интерфейс, который вы имеете в виду
Ответ №1:
Я думаю FieldArray
, что компонент наиболее подходит для вашего варианта использования.
Я изменил ваш пример codesandbox, чтобы использовать его:
import React from "react";
import { Button } from "@material-ui/core";
import { Formik, Form, Field, FieldArray } from "formik";
import { TextField } from "formik-material-ui";
// Here is an example of a form with an editable list.
// Next to each input are buttons for insert and remove.
// If the list is empty, there is a button to add an item.
export default ComboBox = () => (
<Formik
initialValues={{
items: [
{
name: "James",
name2: "Bond"
}
]
}}
onSubmit={(values) =>
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
}, 500)
}
render={({ values }) => (
<Form>
<FieldArray
name="items"
render={(arrayHelpers) => (
<div>
{values.items amp;amp; values.items.length > 0 ? (
values.items.map((item, index) => (
<div key={index}>
<Field
component={TextField}
variant="outlined"
fullWidth
label="Name"
name={`items.${index}.name`}
/>
<Field
component={TextField}
variant="outlined"
fullWidth
label="Name2"
name={`items.${index}.name2`}
/>
<Button
type="button"
onClick={() => arrayHelpers.remove(index)} // remove an item from the list
>
-
</Button>
<Button
type="button"
onClick={() =>
arrayHelpers.insert(index, { name: "", name2: "" })
} // insert an empty item at a position
>
</Button>
</div>
))
) : (
<Button
type="button"
onClick={() => arrayHelpers.push({ name: "", name2: "" })}
>
{/* show this when user has removed all items from the list */}
Add item
</Button>
)}
<div>
<Button type="submit">Submit</Button>
</div>
</div>
)}
/>
</Form>
)}
/>
);
Комментарии:
1. FiledArrayProps — это еще один способ сделать это. У них есть функции удаления, нажатия, вставки для управления полем <Имя поля=»itemsAndServices»> {(fieldArrayProps) => { return (.. fieldArrayProps} /> ); }} </FieldArray>
Ответ №2:
Вы можете использовать функцию setValues
Formik для установки значений формы
{
values.items.map((e, i) => (
<div key={e.i}>
<Button
variant='contained'
onClick={() => {
setValues({
name: '',
name2: '',
items: values.items.filter((newE) => newE !== e), // Remove clicked item
})
}}
>
remove {e.name}
</Button>
</div>
))
}
Полный фрагмент кода приведен ниже:
/* eslint-disable no-use-before-define */
import React, { useState } from 'react'
import { Button } from '@material-ui/core'
import { Formik, Form, Field } from 'formik'
import { TextField } from 'formik-material-ui'
export default function ComboBox() {
const [initialValues, setInitialValues] = useState({
name: '',
name2: '',
items: [],
})
return (
<Formik
initialValues={initialValues}
onSubmit={() => {}}
enableReinitialize
>
{({
isValid,
dirty,
values,
handleChange,
handleBlur,
setFieldValue,
setValues,
}) => {
return (
<Form>
<div>
<Field
name='name'
label='Name'
variant='outlined'
component={TextField}
variant='outlined'
fullWidth
/>
<Field
name='name2'
label='Name2'
variant='outlined'
component={TextField}
variant='outlined'
fullWidth
/>
</div>
<Button
variant='contained'
onClick={() => {
console.log('values', values)
setFieldValue(`items[${values.items.length}]`, {
name: values.name,
name2: values.name2,
})
}}
>
add item
</Button>
{values.items.map((e, i) => (
<div key={e.i}>
<Button
variant='contained'
onClick={() => {
setValues({
name: '',
name2: '',
items: values.items.filter((newE) => newE !== e), // Remove clicked item
})
}}
>
remove {e.name}
</Button>
</div>
))}
</Form>
)
}}
</Formik>
)
}
// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const agents = [
{ name: 'Pathum', id: 1 },
{ name: 'Chamod', id: 2 },
{ name: 'Avishka', id: 3 },
]