返回承诺而不是数据

时间:2019-12-10 19:24:55

标签: reactjs redux axios

最近我在尝试使用axios通过React / Redux书店项目从本地主机获取数据时感到非常沮丧。我使用axios的原因是将App连接到Rails api(后端),并在需要时尝试从数据库更新商店(即书籍列表)。但是,当我尝试将api axios调用的response.data(书本数组)传递给Action Creator时,我在React组件中得到了一个承诺。

  • 图书清单组件

import React from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
import Book from '../components/book';
import { removeBookAction, getBooksAction } from '../actions/index';

class BookList extends React.Component {


  UNSAFE_componentWillMount() {
    this.props.getBooks();
  }

  render() {
    const { books, handleRemoveBook } = this.props;
    console.log(books) // prints Promise {<resolved>: Array(12)} :(
    return (
      <tbody>
        {books.length > 0 ? books.map((book) => (
          <Book key={book.id} item={book} handleRemoval={handleRemoveBook} />
        ))
          : (
            <tr>
              <td>Empty List</td>
            </tr>
          )}
      </tbody>
    );
  }
}

const displayableBooks = (books, theFilter) => {
  //console.log(books)
  if (theFilter === 'All') {
    return books;
  }
  return books.filter(item => item.category === theFilter);
};

// inject store state as props to Booklist component
const mapStateToProps = (state) => {
  return {
    books: displayableBooks(state.books, state.filter),
  };
};

const mapDispatchToProps = (dispatch) => ({
  handleRemoveBook: (book) => {
    dispatch(removeBookAction(book));
  },
  getBooks: () => axios.get('api/v1/books').then(response => {
    dispatch(getBooksAction(response.data));
  }),
});


BookList = connect(mapStateToProps, mapDispatchToProps)(BookList);

export default BookList;

  • Books Action创建者

const creatBookAction = (book) => {
  return {
    type: 'CREATE_BOOK',
    book,
  }
};

const removeBookAction = (book) => ({
  type: 'REMOVE_BOOK',
  id: book.id,
});

const getBooksAction = (books) => {
  return {
    type: 'GET_BOOKS',
    books,
  };

}

const changeFilterAction = (filter) => ({
  type: 'CHANGE_FILTER',
  filter,
});

export { creatBookAction, removeBookAction, changeFilterAction, getBooksAction };

  • Books Reducer

const CREATE_BOOK = 'CREATE_BOOK';
const REMOVE_BOOK = 'REMOVE_BOOK';
const GET_BOOKS = 'GET_BOOKS';


const booksReducer = async (state = [], action) => {

  switch (action.type) {

    case CREATE_BOOK:
      return [
        ...state,
        { ...action.book },
      ];
    case REMOVE_BOOK:
      const index = state.findIndex((value) => value.id === action.id);
      return state.slice(0, index).concat(state.slice(index + 1));
    case GET_BOOKS:
      return action.books;
    default:
      return state;
  }
};

export default booksReducer;

您可以看到上面的代码,我试图在Redux存储和数据库之间创建某种同步,但是我被困在第一步(即获取数据)。我是React / Redux和axios的初学者,因此,如果我的方法(教程中提到的其他方法的组合)效率低下且无法应用,请考虑说明其他替代方法。谢谢:)

2 个答案:

答案 0 :(得分:2)

我意识到自己犯了一个严重的错误。之所以得到承诺而不是实际数据,是因为我的书本缩减器。我使它成为一个异步函数,我想它将不可避免地返回一个promise。

答案 1 :(得分:0)

您应该使用中间件来进行异步调用操作,例如redux thunk

const mapDispatchToProps = (dispatch) => ({
  handleRemoveBook: (book) => {
    dispatch(removeBookAction(book));
  },
  getBooks: () => dispatch(fetchBooksAction());
});

这是您的异步​​操作

const fetchBooksAction = () => (dispatch) => {
  axios.get('api/v1/books').then(response => {
    dispatch(getBooksAction(response.data);
  });
}