React Formik setFieldValue 同一对象内的其他键值

React Formik setFieldValue of other key value within same object

我的目标是选择一个 option select 值,一旦 onChange 发生,它应该设置 2 Fields valuessetFieldValue 有关键同一对象内的值对。

我的问题:为什么当我调用 setFieldValue('meta', value.meta) 时它没有返回键值 meta 而与 setFieldValue('description', value.description) 相同?

我不理解和做错的地方:value 的范围。如果 idvalue 有一个对象子集,我可以使用 .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) => (

无需将 metadescription 传递给您的 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>;