等待道具更新

时间:2017-04-20 17:19:19

标签: javascript reactjs redux

我有这个组件调用fetchSpecificBook动作创建者:

import React, {Component} from 'react';
import { connect } from 'react-redux';
import { fetchSpecificBook } from '../actions/index';

class Cart extends Component {

  constructor(props) {
    super(props);
    this.renderWishlist = this.renderWishlist.bind(this);
  }

  renderWishlist(){
    var quantity;
    var itemID;
    var tmp;
    var myData = this.props.currentCart;
    for (var k=0; k<myData.length; k++){
     tmp = myData[k];
     quantity = tmp.quantity;
     itemID = tmp.itemID;
     fetchSpecificBook(itemID);
     console.log(this.props.currentBook);  // prints undefined
   }
}

  render() {
    return (
      <div>
        <div>
          <h3>Your wishlist</h3>
            {this.renderWishlist()}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state){
  return {
    currentCart: state.bookReducer.currentCart,
    currentBook: state.bookReducer.currentBook
  };
}

export default connect(mapStateToProps, {fetchSpecificBook})(Cart);

fetchSpecificBook动作创建者看起来像这样:

export function fetchSpecificBook(id) {
  let url = 'http://localhost:3001/specific-book/'+id;
  return function (dispatch) {
    axios.get(url)
      .then(response => {
        dispatch({
          type: FETCH_BOOK,
          payload: response
        });
      });
    }
}

和我的减速机:

import {FETCH_BOOKS} from '../actions/types';
const INITIAL_STATE = { currentBook:[] };

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
    case FETCH_BOOK:
      return { ...state, currentBook:action.payload };
    ... other cases
    default:
      return state;
  }
}

因此,当我的组件被渲染时,它会加载renderWishlist(),调用fetchSpecificBook动作创建者将动作发送到reducer。此处currentBook已更新,在我的组件中,由于currentBook,我可以访问mapStateToProps

我的问题是:如何才能等到currentBook更新? 正如您在上面代码中的注释中所看到的那样console.log(this.props.currentBook);返回undefined。 我猜是因为我试图打印this.props.currentBook尚未由reducer更新的内容。

1 个答案:

答案 0 :(得分:4)

有几件事:

  1. 您的购物车将在其道具上收到fetchSpecificBook。这是您应该使用的功能,而不是您导入的功能。 (所以使用this.props.fetchSpecificBook())

  2. 你不应该在renderWishlist中调用fetchSpecificBook,而是在componentDidMount之类的生命周期方法中调用。当reducer具有新状态时,它会向组件提供新的props,并触发render()。因为render()调用renderWishList,所以它会触发fetchSpecificBook AGAIN。这将继续下去。

  3. 重要的是render()只渲染并且不会产生像ajax调用这样的副作用。

    现在,对于你的问题:currentBook的初始状态是一个空数组(这很奇怪,一个空对象{}或未定义会更有意义..)。 这是您将在组件中作为道具收到的初始状态。当axios呼叫完成后,您将收到该响应作为您的新道具。 所以,你真的不能等待&#39;要更新本书,但您可以在渲染方法中执行以下操作:检查值是否与初始状态不同,然后仅控制日志或执行其他操作。如果你使你的初始状态未定义&#39;例如,您可以在渲染方法中执行此操作,而不是空数组:

    { this.props.currentBook && this.renderWishList() }
    

    如果this.props.currentBook有值,则只调用this.renderWishList()。