React-Redux App:“无效的尝试传播不可迭代的实例”问题

时间:2018-10-08 09:50:52

标签: javascript reactjs react-redux

  

开始时,该示例应用程序正常运行。我能看见   我通过浏览器页面和数据库输入的数据。现在,我可以看到   仅通过数据库获取数据,浏览器不显示数据并获取   错误另外:“无效传播不可迭代的尝试   实例”。

有示例代码:

projectActions.js

mounted

projectReducer.js

import {FETCH_BOOK, CREATE_BOOK, DELETE_BOOK} from '../actions/projectTypes';
import axios from 'axios';

const apiUrl = 'http://api/books';

export const createBookSuccess =  (data) => {
  return {
    type: CREATE_BOOK,
    payload: {
      _id: data._id,
      author: data.author,
      publication: data.publication,
      publisher: data.publisher
    }
  }
};

export const deleteBookSuccess = _id => {
  return {
    type: DELETE_BOOK,
    payload: {
      _id
    }
  }
};

export const fetchBook = (books) => {
  return {
    type: FETCH_BOOK,
    books
  }
};

export const createBook = ({ author, publication, publisher }) => {
  return (dispatch) => {
    return axios.post(`${apiUrl}`, {author, publication, publisher})
      .then(response => {
        dispatch(createBookSuccess(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

export const deleteBook = _id => {
  return (dispatch) => {
    return axios.delete(`${apiUrl}/${_id}`)
      .then(response => {
        dispatch(deleteBookSuccess(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

export const fetchAllBooks = () => {
  return (dispatch) => {
    return axios.get(apiUrl)
      .then(response => {
        dispatch(fetchBook(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

rootReducer.js

import {CREATE_BOOK, DELETE_BOOK, FETCH_BOOK} from '../actions/projectTypes';

const projectReducer = (state = [], action) => {
  switch (action.types) {
    case CREATE_BOOK:
      return [...state, action.payload];
    case DELETE_BOOK:
      let afterDelete = state.filter(book => {
        return book._id !== action.payload._id
      });
      return {
        ...state,
        state: afterDelete
      }
    case FETCH_BOOK:
      return action.books;
    default:
      return state;
  }
}

export default projectReducer;

BookListElement.js

import books from './projectReducer';
import {combineReducers} from 'redux';

const rootReducer = combineReducers({
    books: books
});

export default rootReducer;

bookList.js

import React from 'react';
import {connect} from 'react-redux';
import BookList from '../components/bookList';
import {deleteBook} from '../store/actions/projectActions';

const BookListElement= ({books, deleteBook}) => {
  if(!books.length) {
    return (
      <div>
        No Books
      </div>
    )
  }
  return (
    <div>
      {books.map(book => {
        return (
          <BookList book={book} deleteBook={deleteBook} key={book._id} />
        );
      })}
    </div>
  );
}

const mapStateToProps = state => {
  return {
    books: state.books
  };
};

const mapDispatchToProps = dispatch => {
  return {
    deleteBook: _id => {
      dispatch(deleteBook(_id));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(BookListElement);

bookCreate.js

import React from 'react';

const styles = {
  borderBottom: '2px solid #eee',
  background: '#fafafa',
  margin: '.75rem auto',
  padding: '.6rem 1rem',
  maxWidth: '500px',
  borderRadius: '7px'
};

const BookList =  ({ book: { author, publication, publisher, _id }, deleteBook }) => {
  return (
    <div style={styles} key={_id}>
      <h2>{author}</h2>
      <p>{publication}</p>
      <p>{publisher}</p>
      <button className="btn waves-effect waves-light" type="submit" name="action" onClick={() => {deleteBook(_id)}}>
        <i className="large material-icons">delete_forever</i>
      </button>
    </div>
  );
};

export default BookList;
  

我检查了几次代码,并阅读了有关此问题的旧文章   但是我没有找到任何初级的解决方案。如果你那太好了   说我想念的是什么。

编辑:将view.js文件添加为bookList.js。

4 个答案:

答案 0 :(得分:9)

在化简器中,状态应为数组,但是在删除期间,您已返回对象

case DELETE_BOOK:
  let afterDelete = state.filter(book => {
    return book._id !== action.payload._id
  });
  return afterDelete;

答案 1 :(得分:3)

不必回答这个问题,但是也许这可以帮助获得此错误消息并在此SO-Post上绊倒的人

我也遇到了这个错误。就我而言,错误是我尝试克隆的元素实际上是对象而不是数组!

这就是我最终要做的:

var clone = {...this.state.myObj};

(而不是)

var clone = [...this.state.myObj];

我知道,确实很明显,但是我们都从某个地方开始,对吧?

答案 2 :(得分:0)

当您尝试在化简器中复制未定义的数组时,会发生此错误。 例如:

const newList = [...state.someList];

在这种情况下,“ someList”未定义或不是数组。确保您的拼写正确或使用的数组正确。

答案 3 :(得分:0)

我认为您应该将获取响应返回到减速器状态,并且可以在一行中过滤已删除的图书。也许这行得通。

//projectReducer.js
import {CREATE_BOOK, DELETE_BOOK, FETCH_BOOK} from '../actions/projectTypes';

const projectReducer = (state = [], action) => {
  switch (action.types) {
    case CREATE_BOOK:
      return [...state, action.payload];
    case DELETE_BOOK:
      return state = state.filter(book => book._id !== action.payload._id)
    case FETCH_BOOK:
      return state = action.books;
    default:
      return state;
  }
}

export default projectReducer;