I am using react / redux / react-redux to implement a modal form that do an ajax request.
If I am correct, react-redux enable you to :
I am also using redux-saga to handle Ajax request triggered by redux.
However, I have no idea how to trigger an action (ex: close the modal form) when a specific event is triggered from Redux.
Example of code :
class MyFormDialog extends React.Component {
state = {
open: false,
};
handleOpen = () => {
this.setState({open: true});
};
handleClose = () => {
this.setState({open: false});
};
render() {
const actions = [
<FlatButton
label="Cancel"
onTouchTap={this.handleClose}
/>,
<FlatButton
label="Submit"
onTouchTap={this.props.ajaxRequest}
/>,
];
return (
<div>
<MenuItem primaryText="Make a request" onTouchTap={this.handleOpen}/>
<Dialog
title="Make a request"
actions={actions}
modal={true}
open={this.state.open}
onRequestClose={this.handleClose} />
</div>
);
}
}
const mapStateToProps = (state, ownProps) => {
return {
loading: state.isLoading,
success: state.success,
error: state.error,
}
};
const mapDispatchToProps = (dispatch, ownProps) => {
return {
ajaxRequest: (url, tags) => {
dispatch({type: "AJAX_REQUESTED"})
},
}
};
const ConnectedMyFormDialog = connect(
mapStateToProps,
mapDispatchToProps
)(MyFormDialog );
export default ConnectedMyFormDialog ;
Reducers are built as the following:
isLoading = true
when AJAX_REQUESTED
is sent (others are set to false)success = true
when AJAX_SUCCESS
is sent (others are set to false)error = true
when AJAX_FAIL
is sent (others are set to false)So I would like to change state.open
to false when isLoading
change from true
to false
AND success
change to false
to true
.
I have no idea how to do that without messing with state.
Edit:
Here is my sagas code, to handle events:
function* handleAjaxRequest(action) {
try {
yield call(api.doRequest);
yield put({type: "AJAX_SUCCESS"});
} catch (e) {
yield put({type: "AJAX_FAILED"});
}
}
export default function* () {
yield [
takeEvery("AJAX_REQUESTED", handleAjaxRequest),
]
}
You could utilize componentWillReceiveProps()
which is called as soon as your component gets a redux property/state update. There you can react on the redux state changes and set your local component state accordingly.
In your example it would be:
componentWillReceiveProps(nextProps) {
if (nextProps.loading !== this.props.loading &&
nextProps.success !== this.props.success &&
!nextProps.loading && nextprops.success) {
this.setState({ open: false });
}
}
This is exactly the wanted behavior you defined. Imo you should also handle other cases and set state.open more dynamically, but that's beyond the scope of the question.
For reference see here: https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With