Need to dispatch an action based on state or presentaional component's props.
const mapDispatchToProps = (dispatch) => {
return {
onClick: () => {
if (state.someValue || this.props.someValue){
dispatch({type: DO_SOMETHING})
}
}
}
}
and this action is supposed to be intercepted by redux-saga to do some remote fetching tasks, so I can't move this condition into reducer like:
const reducer = (state, action) => {
switch (action.type){
case DO_SOMETHING:
if(state.someValue){
return {...state, //do something}
//I need to fetch some api here, so this won't be a valid way
}
}
}
Can a dispatch fired from inside reducer? so that the new fired dispatch can be intercepted by redux-saga.
A dispatch cannot be fired from a reducer
If checking state must be done by the component, then use the third parameter of connect
, aka mergeProps:
const mapStateToProps = state => ({
someValue: // ...,
// ...
})
const mapDispatchToProps = dispatch => {
return {
onClick: () => dispatch({type: DO_SOMETHING}),
// ...
}
}
const mergeProps = (stateProps, dispatchProps, ownProps) => {
const onClick = () => {
if (stateProps.someValue) {
dispatchProps.onClick();
}
}
return ({
...stateProps,
...dispatchProps,
onClick
})
}
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(MyComponent)
If checking state does not need to be part of the component, then check the state in a saga task:
component:
const mapDispatchToProps = dispatch => {
return {
onClick: () => dispatch({type: MAYBE_DO_SOMETHING}),
// ...
}
}
saga:
function* onMaybeDoSomething(action) {
const someValue = yield select(getSomeValue)
if (someValue) {
yield put({ type: DO_SOMETHING })
}
}
export default function* () {
takeLatest(MAYBE_DO_SOMETHING, onMaybeDoSomething)
}