redux中執行dispatch()方法對store不同節點屬性的干擾?

有兩個不同的reducer

const initialArticlesState = {

list: [],

isFetching: false,

pageIndex: 1,

pageNum: 10

}

const initialStickyArticlesState = {

list: [],

isShowLogo: true,

isFetching: false,

}

function articlesReducer(state = initialArticlesState, action) {

switch (action.type) {

case GET_ARTICLES_REQUEST:

return { ...state, isFetching: true }

case GET_ARTICLES_SUCCESS:

return {

...state,

list: state.list.concat(action.payload),

isFetching: false

}

case GET_ARTICLES_FAILED:

return { ...state, isFetching: false }

default:

return { ...state, isFetching: false }

}

}

function stickyArticlesReducer(state = initialStickyArticlesState, action) {

switch (action.type) {

case GET_STICKY_ARTICLES_REQUEST:

return { ...state, isFetching: true }

case GET_STICKY_ARTICLES_SUCCESS:

if (action.payload.length &> 0) {

return {

...state,

list: state.list.slice(0, 1).concat(action.payload),

isFetching: false,

isShowLogo: false

}

} else {

return { ...state, isFetching: false }

}

case GET_STICKY_ARTICLES_FAILED:

return { ...state, isFetching: false }

default:

return { ...state, isFetching: false }

}

}

先執dispatch({type:"GET_ARTICLES_REQUEST"}),然後執行dispatch({type: "GET_STICKY_ARTICLES_REQUEST"}),基本就是上下行的關係

執行dispatch({type:"GET_ARTICLES_REQUEST"})的時候aticles.isFetching=true,這是對的;然後執行dispatch({type: "GET_STICKY_ARTICLES_REQUEST"})的時候,aticles.isFetching=false了,這裡怎麼將另一個reducer的isFetching變成了false了啊?????

即使是第二個是任何一個dispatch({type:"xxxxxx"}),都會把第一個的isFetching從true變為false

上圖:


謝邀 ??。

在redux 中,有一個 combineReducers 函數,它會組合所有的子 reducer ,並返回最終的 reducer 。

你要組合articlesReducer 和 stickyArticlesReducer ,一定使用到了它 .

附上combineReducers 精簡版的源代碼

function combineReducers(reducers) {
// 這兒返回的函數就是最終的reducer
return function (state, action) {
const keys = Object.keys(reducers)

const newState = {}
keys.forEach(key =&> {
newState[key] = reducers[key](state[key], action)
})
return newState
}
}

可以看到, 對於每一個 dispatch, redux 內部都會走所有的子 reducer 的。

在題主的代碼中,

default:
return { ...state, isFetching: false }
}

這句就會導致,不管發出什麼dispatch, articles 的 isFetching 都會被置為false 。

建議這裡不要在 default: 中更改state,只返回state就好 。

reducer default 有2個用處

  1. 初始化state , 在redux 內部, 會執行 state = dispatch({}) 來初始化state 。
  2. 在combineReducers 後, 防止其它reducer 的dispatch 相互干擾 。

以上 。

不知是否解決了題注的疑惑 。


action是通用的,它不和reducer綁定。reducer應該只處理需要關心的action,你的代碼中寫了:

default:
return { ...state, isFetching: false };

這導致了isFetching被其他的action影響而變成了false。


default寫錯了

按你要的效果,直接return state就好


寫代碼之前,要是思路,一下子我也沒發寫碼去。

首先我覺得你的問題是錯誤的。dispatch只是一個行為,動作action的設計,你有沒有看仔細。

節點干擾這個問題應該不存在,一個state存放數據。問題應該處在一的action上,或者是遞交dispatch不正確。

作答不易,我正在整理我寫的react心得。關注吧!!!


因為 redux 最終會把所有的 reducer 合併成一個對象,所以你的 isFetching 其實用的同一個key,可以給 reducer 加命令空間隔離開來。如

combineReducers({
articles: articlesReducer,
sticky: stickyArticlesReducer
})


推薦閱讀:

為什麼 React 推崇 HOC 和組合的方式,而不是繼承的方式來擴展組件?
說說對react中JSX語法的理解?
前端發展太快,有些小伙只會用react(了解api),招個jquery熟練的外包較難,如何看?

TAG:前端開發 | JavaScript | React | Redux |