收听redux saga中组件的reducer状态更改

问题描述 投票:2回答:1

我在我的反应应用程序中使用redux-saga。我必须获取订单列表并在组件中显示。我已经创建了动作,减速器和传奇。

我正在使用传奇中的API

冒险故事

import { call, put } from "redux-saga/effects";
import { path } from "ramda";
import OrdersActions from "../Redux/OrdersRedux";
export function* getOrders(api, action) {
  const { header } = action;
  console.log("order header", action);
  // make the call to the api
  const response = yield call(api.getOrders, header);
  console.log(response);
  if (response.ok) {
    yield put(OrdersActions.success(response.data));
    // do data conversion here if needed
  } else {
    yield put(OrdersActions.failure());
  }
}

减速器

import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'

/* ------------- Types and Action Creators ------------- */

const { Types, Creators } = createActions({
  getOrders: ['header'],
  success: ["data"],
  failure: [],
})

export const OrderTypes = Types
export default Creators

/* ------------- Initial State ------------- */

export const INITIAL_STATE = Immutable({
  new_orders: [],
  fetching: null,
  error: null,
})

/* ------------- Reducers ------------- */

// request the avatar for a user

export const getOrdersRequest = (state) =>
  state.merge({ fetching: true })

// successful avatar lookup
export const success = (state, action) => {
  const { data } = action;
  return state.merge({ fetching: false, error: null, new_orders: data.data.new_orders })
}

// failed to get the avatar
export const failure = (state) =>
  state.merge({ fetching: false, error: true })


/* ------------- Hookup Reducers To Types ------------- */

export const reducer = createReducer(INITIAL_STATE, {
  [Types.GET_ORDERS]: getOrdersRequest,
  [Types.SUCCESS]: success,
  [Types.failure]: failure,
})

MyComponent.js

class OrdersScreen extends Component {
  static navigationOptions = getHeaderStyle("Orders");

  constructor(props) {
    super(props);
    this.state = {
      new_orders: this.props.order_details.new_orders
    }
  }


  componentWillMount() {
    this.props.getOrders(this.getHeader());
  }


  componentWillReceiveProps(newProps, props) {
    if (newProps.order_details.new_orders.length > 0) {
      this.setState({
        new_orders: newProps.order_details.new_orders
      })
    }
  }

  render() {
    return (
      <View style={{ flex: 1, flexDirection: 'column', justifyContent: "flex-start" }}>
        <View style={{ padding: 10, flexDirection: 'row' }}>
          <Text style={{ flex: 3 }}>Order</Text>
        </View >
        {
            this.state.new_orders.map((item)=>{
                return<div>{item.order_id}</div>
            })
        }
        <View>
          <Button label="Make Payment" onPress={this.onMakePaymentClick()} />
        </View >
      </View>
    )
  }

  getHeader() {
    const { session_id } = this.props;
    return { "x-session-id": session_id };
  }

  onMakePaymentClick = () => {
    this.props.submitOrders();
  }
}


const mapStateToProps = (state, ownProps) => {
  return {
    order_details: state.order_details,
  }
}



const mapDispatchToProps = (dispatch) => ({
  getOrders: (header) => dispatch(OrdersActions.getOrders(header)),
})

export default connect(mapStateToProps, mapDispatchToProps)(OrdersScreen)

我的问题是有没有其他方法可以知道a值在商店中被更改并获得更改的值?

我正在使用componentWillReceiveProps方法对商店中的任何新变化。

现在我想发送另一个动作“MakePayment”并点击另一个api,如果响应正常,我想更改屏幕,否则显示错误消息。

如您所见,我在componentWillReceiveProps中将new_orders设置为state。如果我发送“MakePayment”操作,这将再次调用componentWillReceiveProps并且订单将重新呈现。

怎么避免这个?还有其他任何组件可以监听商店的变化和价值变化吗?

reactjs redux react-redux redux-saga
1个回答
1
投票

首先,您应该从componentDidMount调度您的操作。 componentWillMount docs解释了原因。

其次,您不需要使用componentWillReceiveProps来获取更改,因为您只需要发送一次getOrders。数据直接进入你的new_orders道具。事实上,既然你只关心new_orders,你应该把它直接设置为道具。这样你的组件直接观察到new_orders的变化。

最后,如果您调用“MAKE_PAYMENT”操作,则不会生成重新呈现,因为付款数据不会出现在您的道具或状态中。请记住,当您在道具中有数据时,除非您有充分的理由,否则无需将其传递到状态。

© www.soinside.com 2019 - 2024. All rights reserved.