更新对象数组中的数组值

Updating array value inside array of objects

我有一个像这样的对象“电影”数组:

{
 id: "some id",
 title: "some title",
 actors: []
}

如您所见,演员数组保持为空,因为我在添加电影时没有添加演员。我想稍后在 http://localhost:3000/movies/<movieId> 上添加演员。 我通过这个表格来做到这一点。我只是从现有的演员列表中选择一个演员。

const PostForm = ({ addActorToMovie, movie, actors, history }, props) => {
  const handleSubmit = (values) => {
    addActorToMovie(values);
    // history.push(`/movies/${movie.id}`);
  };
  let actorsList =
    actors.length > 0 &&
    actors.map((item, i) => {
      return (
        <option value={`${item.firstName}, ${item.lastName}`}>
          {item.firstName + item.lastName}{" "}
        </option>
      );
    });

  return (
    <div>
      <h3>Add Actor</h3>
      <Formik
        initialValues={{
          actor: "",
        }}
        onSubmit={(values) => handleSubmit(values)}
        enableReinitialize={true}
      >
        <Form>
          <Field name="actor" component="select">
            <option value="null"> </option>
            {actorsList}
          </Field>
          <button type="submit">Zatwierdz</button>
        </Form>
      </Formik>
    </div>
  );
};

const mapStateToProps = (state, props) => {
  return {
    movie: state.movie,
    actors: state.actors,
  };
};

const mapDispatchToProps = {
  addActorToMovie,
};

export default withRouter(
  connect(mapStateToProps, mapDispatchToProps)(PostForm)
);

表格有效。尽管没有为我的 actors array 增加价值。它在 movies 数组下创建一个新对象,如下所示:

actors: {actor: 'Some actor name'}

我的减速器看起来像这样。可能这就是问题的根源,但我真的不知道该怎么做。

export const movieReducer = (state = [], action) => {
  switch (action.type) {
    case "MOVIE_ADD":
      return [...state, action.payload];
    case "MOVIE_DELETE":
      return [...state.filter((el) => el.id !== action.payload.id)];
    case "MOVIEACTOR_ADD":
      return {
        ...state,
        actors: action.payload
      };
    default:
      return state;
  }
};

我想做的当然是将我在 Formik 中输入的演员推送到指定电影的数组中。

您不想声明一个新的 actors 属性 只是有效负载,而是想将其附加到现有的 actors 数组。但是,您首先需要知道要更新的是哪个电影对象,因此也需要在操作负载中发送。

更新提交处理程序以发送电影 ID 和要添加的演员。

const handleSubmit = ({ actor }) => {
  addActorToMovie({
    movieId: movie.id,
    actor,
  });
};

更新 reducer case 以映射 movies 数组,它在 movieReducer 中似乎是 state。浅复制电影 state 数组,对于匹配的电影 ID,浅复制并将演员附加到演员数组。

case "MOVIE_ACTOR_ADD":
  const { actor, movieId } = action.payload;
  return state.map(movie => movie.id === movieId
    ? {
      ...movie,          // <-- shallow copy movie object
      actors: [
        ...movie.actors, // <-- shallow copy existing array
        actor            // <-- append new actor payload
      ],
    }
    : movie
  );

将电影添加到状态时,请确保 actors 数组 属性 存在。如果您不向它传递 MOVIE_ADD 动作负载,则在添加电影时在 reducer 中处理它。

case "MOVIE_ADD":
  return [
    ...state,
    { ...action.payload, actors: [] },
  ];