Как сделать состояние итеративным и разрешить «Необработанное отклонение (TypeError): state.story не является итеративным»?

#javascript #reactjs #redux #axios

#javascript #reactjs #redux #axios

Вопрос:

Я отправляю несколько файлов и некоторые другие данные через redux и axios на свой серверный сервер. Однако, когда я это делаю, я получаю следующее сообщение об ошибке Unhandled Rejection (TypeError): state.story is not iterable . Хотя ошибка возникает в моем интерфейсе react js, данные успешно отправляются на мой сервер. Когда я отправляю обычные пары ключей vlaue и без массива, он также работает нормально.

Теперь мне интересно, как я могу сделать state.story итеративным? Или более общий подход к этой проблеме?

 // creating the form data
onClickUpload (e){
  let files = this.state.image;
  let formData = new FormData();

  formData.append('title', "Some_Title")

  for (var i = 0; i < files.length; i  ) {
    formData.append(`story_media[${i}]isTitlePicture`, files[i].isTitlePicture)
    formData.append(`story_files[${i}]files`, files[i].file)
  }

    this.props.addStory(formData);

}
 
 // ADD Story Action
export const addStory = formDataStory => (dispatch, getState) =>
new Promise((resolve, reject) => {
  axios.post(apiBase  "/story/createupdatedestroy/", formDataStory, tokenConfig(getState) )
    .then(res => {
      dispatch(createMessage({ addStory: "Story Added" }));
      dispatch({
        type: ADD_STORY,
        payload: res.data
      });
      resolve(res);
    })
    .catch(err => {
      reject(err);
      dispatch(returnErrors(err.response.data, err.response.status))
    }
  );
 
 // Add STory Reducer
const initialState = {
  story: [],
  isFetching: "idle"
};

export default function (state = initialState, action) {
  switch (action.type) {
case GET_STORY_REQUEST:
      return {
        ...state,
        isFetching: "loading"
      };

case GET_STORY_SUCCESS:
      return {
        ...state,
        story: action.payload,
        isFetching: "success"
      };

case GET_STORY_FAILURE:
      return {
      isFetching: "failure"
      };

case GET_SINGLE_STORY:
     return {
        ...state,
        story: state.story.filter(story => story.id !== action.payload)
      };

case DELETE_STORY:
      return {
        ...state,
        story: state.story.filter(story => story.id !== action.payload)
      };

case EDIT_STORY:
      return {
        ...state,
        story: state.story.filter(story => story.id  !== action.payload)
      };


case ADD_STORY:
      return {
        ...state,
        story: [...state.story, action.payload]
      };



    default:
      return state;
  }
}
 

Комментарии:

1. Это весь редуктор?

2. Теперь это весь редуктор для story.

3.Спасибо. GET_STORY_FAILURE не копирует существующее состояние. Если вы также распространяете state его в возвращаемом объекте состояния, устраняет ли это или изменяет ошибку каким-либо образом? Я просто ищу все, что может больше state.story не быть массивом. Установлены ли и запущены ли в вашем браузере redux-dev-tools, чтобы вы могли проверять свое состояние и вручную отправлять действия или, по крайней мере, отслеживать их в реальном времени?

4. Спасибо тебе @Drew Reese! это работает, если вы опубликуете это как ответ, я могу принять его.

Ответ №1:

Проблема

Один из ваших случаев редуктора неправильно копирует объект состояния. Он пренебрегает копированием текущего состояния в новый объект состояния.

 case GET_STORY_FAILURE:
  return {
    isFetching: "failure"
  };
 

Решение

Скопируйте существующее состояние в новый объект состояния.

 case GET_STORY_FAILURE:
  return {
    ...state,
    isFetching: "failure"
  };