为什么mapStateToProps返回undefined?

时间:2018-03-12 05:34:39

标签: reactjs react-redux

我创建动作和减速器并在console.log中使用假API站点进行测试我有我的帖子列表但我无法在mapStateToProps中使用它们。 当我在mapStateToProps状态下写console.log(state)时会显示正确的数据但是当我写consloe.log(state.books.data)时返回undefined。

tanx帮助我

这是我的代码

//actions
import axios from 'axios';
const ROOT_URL = 'https://jsonplaceholder.typicode.com/posts';
export const FETCH_BOOKS = 'FETCH_BOOKS';
export const fetchBooks = () => {
  const request = axios.get(ROOT_URL);
  return {
    type: FETCH_BOOKS,
    payload: request
  }
};

//reducer
import {FETCH_BOOKS} from '../actions/actions_books';
const bookInitialState = [];
export const booksReducers = (state = bookInitialState, action) => {
  switch (action.type) {
    case FETCH_BOOKS:
      console.log(action.payload);
      return action.payload;
    default:
      return state;
  }
};

import {combineReducers} from 'redux';
import {booksReducers} from './reducer_books';

const rootReducer = combineReducers({
  books: booksReducers
});
export default rootReducer;

//component/BookList.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {fetchBooks} from '../actions/actions_books';
import _ from 'lodash'
class BooksList extends Component {
  componentDidMount = () => {
    this.props.fetchBooks();
  };
  renderBooks = () => {
    _.map(this.props.books, (book) => {
        return <li className="list-group-item">{book.id}</li>
      }
    )
  };
  render() {
    return (
      <ul className="list-group">
        {this.renderBooks()}
      </ul>
    );
  }
}
const mapStateToProps = (state) => {
  console.log('state', state.books);
  return {books: state.books}
};
export default connect(mapStateToProps, {fetchBooks})(BooksList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

3 个答案:

答案 0 :(得分:0)

问题非常简单,您在async函数中触发componentDidMount请求,该请求在渲染周期后执行。但是,即使您在componentWillMount中有请求,由于请求在获得结果之前是异步的,因此将调用渲染周期,因此mapStateToProps因此state.books.data会给您{undefined 1}}。当异步请求成功并且您拥有数据时,您可以访问state.books.data

答案 1 :(得分:0)

目前,网络请求已在fetchBooks动作创建者中完成。

Network requests should be inlined in componentDidMount生命周期方法部分是为了从动作创建者(记住SRP)移动这样的逻辑并在分派动作之前解析网络请求。 e.g。

class BooksList extends Component {
  componentDidMount = () => {
    axios.get(ROOT_URL)
     .then(response => this.props.fetchBooksSuccess(response.data))
     .catch(err => this.props.fetchBooksError(err));
  };
...
}

...

export const fetchBooksSuccess = (data) => {
  return {
    type: FETCH_BOOKS_SUCCESS,
    payload: data
  }
};

使用redux-saga时的情况通常是将操作分派给FETCH_BOOKS并使网络请求在定义的传奇中生效。

答案 2 :(得分:0)

你需要使用@Shubham Khatri提到的.then()的承诺axios

API调用将始终是异步的,您的javascript(reactjs)将不会等待响应。这就是您获得undefined价值的原因。

我觉得使用Promise解析API调用就是解决方案。