简体   繁体   English

组件不显示更新的Redux状态

[英]component does not display updated redux state

I have a Meals page with meal cards that toggles a modal with details about the clicked meal when the card is clicked: 我有一个包含餐卡的“餐”页面,单击该卡后,该模式会切换一个模式,其中包含有关所餐的详细信息:

{
  this.props.filteredMeals.map(m => {
    return (
      <div onClick={() => this.props.toggleMealModal(m)} key={m.id}>
        <MealCard meal={m} />
      </div>
    )
  })
}

toggleMealModal(meal) updates the meal inside my redux store. toggleMealModal(meal)更新我的redux商店中的餐点。

meal: {
  description: "Marre des sashimis de thon ou de saumon ? Tentez le maquereau!",
  fees: "80",
  id: 27,
  ingredients: "maquereau cru",
  name: "Sashimi de maquereau",
  no_fees_price: 599,
  original_price: 850,
}

inside my MealModal I have a PaymentContainer child component that also mounts when the modal is toggle and calls an action: 在我的MealModal内部,我有一个PaymentContainer子组件,该组件在模式切换并调用动作时也会挂载:

componentDidMount() {
    this.props.getUserCredit(this.props.meal.no_fees_price, this.props.meal.fees);
  } 

where this.props.meal is fetched from my redux store via mapStateToProps . 其中this.props.meal是通过我的终极版商店获取mapStateToProps

the getUserCredit() is the following action: getUserCredit()是以下操作:

export const getUserCredit = (noFeesPrice, fees) => {
  return dispatch => {
    axios.get('/get_user_credit')
    .then(res => {
      dispatch(setUserCredit(parseInt(res.data.credit) / 100));
      parseInt(noFeesPrice) + parseInt(fees) - parseInt(res.data.credit) < 0 ?
        dispatch(setMealPrice(0, (parseInt(noFeesPrice) + parseInt(fees)) / 100))
        :
        dispatch(setMealPrice((parseInt(noFeesPrice) + parseInt(fees) - parseInt(res.data.credit)) / 100, parseInt(res.data.credit) / 100)
          );
    })
    .catch(err => console.log(err));
  }
}

and then a child component displays the mealPrice , fetched from the redux store (and supposedly updated by getUserCredit() ). 然后一个子组件显示mealPrice ,从了Redux店取出(并通过所谓更新getUserCredit()

The problem is: the very first clicked meal card displays nothing at this.props.mealPrice , and when other cards are clicked and the modal mounts, this.props.mealPrice displays the price from the previously clicked meal card. 问题是:第一次单击的餐卡在this.props.mealPrice什么也不显示,而当单击其他卡并进行模态安装时, this.props.mealPrice显示以前单击的餐卡的价格。

How can I change my code so that the right price mounts with the right meal ? 如何更改我的代码,以使正确的价格与正确的餐食相吻合?

EDIT: relevant reducers and action creator code : 编辑:相关的reducers和动作创建者代码:

export const setUserCredit = (credit = 0) => ({
  type: SET_USER_CREDIT,
  payload: { credit }
});

export const setMealPrice = (mealPrice = null, amountOff = 0) => ({
  type: SET_MEAL_PRICE,
  payload: { mealPrice, amountOff }
});

case SET_USER_CREDIT: {
  return {
    ...state,
    credit: action.payload.credit
  }
}
case SET_MEAL_PRICE: {
  return {
    ...state,
    amountOff: action.payload.amountOff,
    mealPrice: action.payload.mealPrice
  }
}

I recommend you to use status indicators while working with APIs. 我建议您在使用API​​时使用状态指示器。

Very simplified, you could build some action creators like: 非常简化,您可以构建一些动作创建者,例如:

const getUserCreditStart = () => ({
  type: GET_USER_CREDIT_START,
});

const getUserCreditSuccess = () => ({
  type: GET_USER_CREDIT_SUCCESS,
});

const getUserCreditError = payload => ({
  type: GET_USER_CREDIT_ERROR,
  payload,
});

In your getUserCredit function you can then dispatch these actions accordingly: 然后,您可以在getUserCredit函数中分派以下操作:

export const getUserCredit = (noFeesPrice, fees) => (dispatch) => {
    dispatch(getUserCreditsStart());
    return axios.get('/get_user_credit')
      .then(res => {
        dispatch(setUserCredit(parseInt(res.data.credit) / 100));
        parseInt(noFeesPrice) + parseInt(fees) - parseInt(res.data.credit) < 0
        ? dispatch(setMealPrice(0, (parseInt(noFeesPrice) + parseInt(fees)) / 100))
        : dispatch(setMealPrice((parseInt(noFeesPrice) + parseInt(fees) - parseInt(res.data.credit)) / 100, parseInt(res.data.credit) / 100));
    })
    .then(() => dispatch(getUserCreditSuccess()))
    .catch(err => dispatch(getUserCreditError(err)))
}

And then, you need to add them to a reducer. 然后,您需要将它们添加到减速器中。 Btw. 顺便说一句。 typeToReducer might be a good choice here. 在这里typeToReducer可能是一个不错的选择。 :) :)

In the reducer you need to set the status on the different actions that got dispatched. 在减速器中,您需要为已调度的不同操作设置状态。

const initialState = {
  status: 'INITIAL',
};

...

case GET_USER_CREDIT_START: {
  return {
    ...state,
    status: 'START',
  }
}

case GET_USER_CREDIT_SUCCESS: {
  return {
    ...state,
    status: 'SUCCESS',
  }
}

case GET_USER_CREDIT_ERROR: {
  return {
    ...state,
    status: 'ERROR',
    error: action.payload,
  }
}

Well, and in your PaymentContainer component you then can wait for the answer and show a loading bar while you are waiting (the status information you get with mapStateToProps like you do with the results). 好了,然后在您的PaymentContainer组件中,您可以等待答案并在等待时显示加载栏(通过mapStateToProps获取的状态信息与处理结果一样)。 In case of an error, you are able to display the error as well. 如果发生错误,您也可以显示该错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM