2017-04-20 33 views
1

我有这个分量称之为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将动作发送给减速器的动作创建器。这里currentBook得到更新,并在我的组件我可以访问currentBook感谢mapStateToProps

我的问题是:我如何等待,直到currentBook已更新? 正如你可以从我的评论console.log(this.props.currentBook);上面的代码看到返回未定义。 我想因为我试图打印this.props.currentBook,它还没有被reducer更新。

回答

3

有几件事情:

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

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

render()只呈现并不产生副作用(如ajax调用)很重要。

现在,对于你的问题:currentBook的初始状态是一个空数组(这很奇怪,一个空对象{}或未定义会更有意义..)。 这是您将在组件中作为道具收到的初始状态。当axios呼叫完成后,您会收到作为新道具的回复。 因此,您无法真正'等待'更新本书,但您可以在您的呈现方法中执行以下操作:检查值是否与初始状态不同,并且只有在控制台日志或执行其他操作时才会执行此操作。如果你让你的初始状态“未定义”,而不是例如空数组,你可以在你的渲染方法做到这一点:

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

这只会调用this.renderWishList()如果this.props.currentBook有值。

+0

很好的答案!不过,为了您的第二点,我宁愿在'componentDidMount'上使用'fetchSpecificBook',而不是在构造函数中 - 为了好的做法。 –

+0

同意。为清晰起见进行编辑。 – 0xRm