我在我的反应应用程序中使用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并且订单将重新呈现。
怎么避免这个?还有其他任何组件可以监听商店的变化和价值变化吗?
首先,您应该从componentDidMount调度您的操作。 componentWillMount docs解释了原因。
其次,您不需要使用componentWillReceiveProps
来获取更改,因为您只需要发送一次getOrders
。数据直接进入你的new_orders
道具。事实上,既然你只关心new_orders
,你应该把它直接设置为道具。这样你的组件直接观察到new_orders
的变化。
最后,如果您调用“MAKE_PAYMENT”操作,则不会生成重新呈现,因为付款数据不会出现在您的道具或状态中。请记住,当您在道具中有数据时,除非您有充分的理由,否则无需将其传递到状态。