React Formik setFieldValue 同一对象内的其他键值
React Formik setFieldValue of other key value within same object
我的目标是选择一个 option select
值,一旦 onChange
发生,它应该设置 2 Fields
values
和 setFieldValue
有关键同一对象内的值对。
我的问题:为什么当我调用 setFieldValue('meta', value.meta)
时它没有返回键值 meta
而与 setFieldValue('description', value.description)
相同?
我不理解和做错的地方:value
的范围。如果 id
的 value
有一个对象子集,我可以使用 .description
和 .meta
但它们在同一个对象中。我怎样才能正确访问它?
我用过的例子:Formik Select with Other Option and Country and Regions
我的json:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "1",
"created": "July 27, 2021, 10:21 PM",
"modified": "August 12, 2021, 09:00 PM",
"name": "Enter the Dragon",
"description": "One of the greatest Kung Fu movies on my list.",
"meta": {
"director": "Robert Clouse",
"studio": "Warner Bros",
},
},
{
"id": "2",
"created": "July 27, 2021, 10:22 PM",
"modified": "August 12, 2021, 09:01 PM",
"name": "Iron Monkey",
"description": "Another Kung Fu favorite.",
"meta": {
"director": "Yuen Wo Ping",
"studio": "Warner Bros",
},
},
}
我的 useEffect 和 JSX:
const [movieList, setMovieList] = useState([]);
useEffect(() => {
const getMovieList = async () => {
try {
const { data } = await fetchContext.authAxios.get(`/movies/`);
setMovieList(data.results);
// console.log(data);
} catch (err) {
console.log(err);
}
};
getMovieList();
}, [fetchContext]);
const initialValues = {
collection_name: '',
movies: [
{
name: '',
order: '',
label: '',
meta: '',
description: '',
},
],
};
<Formik initialValues={initialValues}>
{({ isSubmitting, values, setFieldValue, handleChange }) => (
<Form>
<div className="row">
<div className="col-md-6 col-xl-3">
<div className="form-group">
<label htmlFor="name">COLLECTION NAME</label>
<Field className="form-control" name="collection_name" type="text" />
</div>
</div>
</div>
<div className="row">
<div className="col-12">
<h3 className="pt-3">CREATE NEW COLLECTION</h3>
</div>
</div>
<FieldArray name="movies">
{({ insert, remove, push }) => (
<>
{values.movies.length > 0 &&
values.movies.map((index) => (
<div className="row" key={index}>
<div className="col-11">
<div className="row">
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.name`}
>
NAME
</label>
<Field
className="form-control"
as="select"
name={`movies.${index}.name`}
onChange={(event) => {
handleChange(event);
const { value } = event.target;
setFieldValue(`movies.${index}.meta`, value.meta);
setFieldValue(`movies.${index}.description`, value.description);
}}
>
<option defaultValue>...</option>
{movieList &&
movieList.map((i) => (
<option key={i.id} value={i.id}>
{i.name}
</option>
))}
</Field>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.order`}
>
ORDER
</label>
<Field
className="form-control"
name={`movies.${index}.order`}
type="text"
/>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.label`}
>
LABEL
</label>
<Field
className="form-control"
name={`movies.${index}.label`}
type="text"
/>
</div>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.meta`}
>
META DATA
</label>
<textarea
value={values.meta}
id="options"
className="form-control"
name={`movies.${index}.meta`}
type="textarea"
rows="4"
onChange={handleChange}
/>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.description`}
>
DESCRIPTION
</label>
<textarea
value={values.description}
id="options"
className="form-control"
name={`movies.${index}.description`}
type="textarea"
rows="4"
onChange={handleChange}
/>
</div>
</div>
</div>
<div className="col-1">
<button
type="button"
className="btn"
onClick={() => remove(index)}
>
Delete
</button>
</div>
</div>
))}
<button
type="button"
className="btn"
onClick={() => push({ step: '', label: '' })}
>
Add Movie Fields
</button>
</>
)}
</FieldArray>
<div className="my-3">
<div className="border-bottom" />
</div>
<button
className="btn primary_btn float-right mb-5"
type="submit"
disabled={isSubmitting}
>
SUBMIT
</button>
</Form>
)}
</Formik>
如果此问题已得到解答,请让我参考正确回答的问题。
map
方法的第一个参数是数组中的项目而不是索引。所以你需要把它改成
values.movies.map((movie, index) => (
无需将 meta
和 description
传递给您的 setFieldValue,您需要传递
<Field
className="form-control"
as="select"
name={`movies.${index}.name`}
onChange={(event) => {
handleChange(event);
// find the selected movie from the movie list
const selectedMovie = movieList.find(movie => movie.id === event.target.value);
setFieldValue(`movies.${index}.meta`, selectedMovie.meta);
setFieldValue(`movies.${index}.description`, selectedMovie.description);
}}
>
<option defaultValue>...</option>
{movieList &&
movieList.map((i) => (
<option key={i.id} value={i.id}>
{i.name}
</option>
))}
</Field>;
我的目标是选择一个 option select
值,一旦 onChange
发生,它应该设置 2 Fields
values
和 setFieldValue
有关键同一对象内的值对。
我的问题:为什么当我调用 setFieldValue('meta', value.meta)
时它没有返回键值 meta
而与 setFieldValue('description', value.description)
相同?
我不理解和做错的地方:value
的范围。如果 id
的 value
有一个对象子集,我可以使用 .description
和 .meta
但它们在同一个对象中。我怎样才能正确访问它?
我用过的例子:Formik Select with Other Option and Country and Regions
我的json:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "1",
"created": "July 27, 2021, 10:21 PM",
"modified": "August 12, 2021, 09:00 PM",
"name": "Enter the Dragon",
"description": "One of the greatest Kung Fu movies on my list.",
"meta": {
"director": "Robert Clouse",
"studio": "Warner Bros",
},
},
{
"id": "2",
"created": "July 27, 2021, 10:22 PM",
"modified": "August 12, 2021, 09:01 PM",
"name": "Iron Monkey",
"description": "Another Kung Fu favorite.",
"meta": {
"director": "Yuen Wo Ping",
"studio": "Warner Bros",
},
},
}
我的 useEffect 和 JSX:
const [movieList, setMovieList] = useState([]);
useEffect(() => {
const getMovieList = async () => {
try {
const { data } = await fetchContext.authAxios.get(`/movies/`);
setMovieList(data.results);
// console.log(data);
} catch (err) {
console.log(err);
}
};
getMovieList();
}, [fetchContext]);
const initialValues = {
collection_name: '',
movies: [
{
name: '',
order: '',
label: '',
meta: '',
description: '',
},
],
};
<Formik initialValues={initialValues}>
{({ isSubmitting, values, setFieldValue, handleChange }) => (
<Form>
<div className="row">
<div className="col-md-6 col-xl-3">
<div className="form-group">
<label htmlFor="name">COLLECTION NAME</label>
<Field className="form-control" name="collection_name" type="text" />
</div>
</div>
</div>
<div className="row">
<div className="col-12">
<h3 className="pt-3">CREATE NEW COLLECTION</h3>
</div>
</div>
<FieldArray name="movies">
{({ insert, remove, push }) => (
<>
{values.movies.length > 0 &&
values.movies.map((index) => (
<div className="row" key={index}>
<div className="col-11">
<div className="row">
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.name`}
>
NAME
</label>
<Field
className="form-control"
as="select"
name={`movies.${index}.name`}
onChange={(event) => {
handleChange(event);
const { value } = event.target;
setFieldValue(`movies.${index}.meta`, value.meta);
setFieldValue(`movies.${index}.description`, value.description);
}}
>
<option defaultValue>...</option>
{movieList &&
movieList.map((i) => (
<option key={i.id} value={i.id}>
{i.name}
</option>
))}
</Field>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.order`}
>
ORDER
</label>
<Field
className="form-control"
name={`movies.${index}.order`}
type="text"
/>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.label`}
>
LABEL
</label>
<Field
className="form-control"
name={`movies.${index}.label`}
type="text"
/>
</div>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.meta`}
>
META DATA
</label>
<textarea
value={values.meta}
id="options"
className="form-control"
name={`movies.${index}.meta`}
type="textarea"
rows="4"
onChange={handleChange}
/>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`movies.${index}.description`}
>
DESCRIPTION
</label>
<textarea
value={values.description}
id="options"
className="form-control"
name={`movies.${index}.description`}
type="textarea"
rows="4"
onChange={handleChange}
/>
</div>
</div>
</div>
<div className="col-1">
<button
type="button"
className="btn"
onClick={() => remove(index)}
>
Delete
</button>
</div>
</div>
))}
<button
type="button"
className="btn"
onClick={() => push({ step: '', label: '' })}
>
Add Movie Fields
</button>
</>
)}
</FieldArray>
<div className="my-3">
<div className="border-bottom" />
</div>
<button
className="btn primary_btn float-right mb-5"
type="submit"
disabled={isSubmitting}
>
SUBMIT
</button>
</Form>
)}
</Formik>
如果此问题已得到解答,请让我参考正确回答的问题。
map
方法的第一个参数是数组中的项目而不是索引。所以你需要把它改成
values.movies.map((movie, index) => (
无需将 meta
和 description
传递给您的 setFieldValue,您需要传递
<Field
className="form-control"
as="select"
name={`movies.${index}.name`}
onChange={(event) => {
handleChange(event);
// find the selected movie from the movie list
const selectedMovie = movieList.find(movie => movie.id === event.target.value);
setFieldValue(`movies.${index}.meta`, selectedMovie.meta);
setFieldValue(`movies.${index}.description`, selectedMovie.description);
}}
>
<option defaultValue>...</option>
{movieList &&
movieList.map((i) => (
<option key={i.id} value={i.id}>
{i.name}
</option>
))}
</Field>;