2016-06-13 88 views
0

我試圖採用在'容器組件'(又名智能組件)&中執行所有操作,然後只是將數據傳遞到「表示組件」的理念。驗證React-Redux中「容器組件」中的觸發事件

我被困在這一點,我需要驗證用戶操作(事件觸發),然後我將動作發送到Reducer。我想這樣做的方法是通過在'mapDispatchToProps'內的函數中驗證事件。

的代碼看起來是這樣的:

const mapStateToProps = ({ oneState, twoState }) => { 
    return({ 
     oneState : oneState, 
     twoState : twoState 
    }); 
}; 

const mapDispatchToProps = (dispatch) => { 
    return({ 
     dispatchOneAction :() => { 
    // do the validation here. The validation requires access to 
    // the 'oneState' obj above in the 'mapStateToProps' 
     } 
    }); 
}; 

const C_Element = connect(mapStateToProps, mapDispatchToProps)(Ele); 

我的問題是,這可能嗎?或者我必須在presentation component下游執行驗證,然後調用'dispatchOneAction'函數?

+2

爲什麼不直接定義在驗證容器組件的功能,並把它作爲一個道具呈現組件? – kinakuta

+0

感謝@kinakuta這是一個非常好的建議 – Kayote

回答

3

connect允許第三參數調用mergeProps

連接([mapStateToProps],[mapDispatchToProps],[mergeProps], [選項])

mergeProps是一個函數,它將接收來自您的mapStateToPropsmapDispatchToProps和提供給您的組件的道具的結果。它允許你使用它們來操作和返回應用到你的組件的最終道具。這可能是根據您的狀態使用其他驗證邏輯修飾您的動作創作者的機會。你可以做任何你喜歡的事,返回一套全新的道具應用到你的組件上。

例如,使用您所描述的情況:

const mapStateToProps = ({ oneState, twoState }) => { 
    return({ 
    oneState : oneState, 
    twoState : twoState 
    }); 
}; 

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ 
    successAction: MyActions.successAction, 
    failAction: MyActions.failAction 
    }, dispatch); 
}; 

const mergeProps = (stateProps, dispatchProps, ownProps) => { 
    const { oneState, twoState } = stateProps; 
    const { successAction, failAction } = dispatchProps; 
    const validatorAction =() => { 
    if (oneState && twoState) { 
     successAction(); 
    } else { 
     failAction(); 
    } 
    } 

    return Object.assign(
    {}, 
    stateProps, 
    // We are providing new actions props 
    { validatorAction }, 
    ownProps   
); 
} 

const C_Element = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Ele); 

參考official react-redux docs以獲得更多信息。


另一種方法是使用基於redux-thunk的操作。這使您可以將行爲創建者中的邏輯封裝到訪問狀態中。您還可以在您的thunk操作中觸發進一步的操作。

例如:

function validatingAction() { 
    return (dispatch, getState) => { 
    const { stateOne, stateTwo } = getState(); 

    if (stateOne && stateTwo) { 
     dispatch(successAction()); 
    } 

    dispatch(failedAction()); 
}; 
+0

一個美妙的答案,謝謝你是如此詳盡。 – Kayote

+0

mergeProps方法的一個問題是它在容器的render方法中被調用,這意味着你不應該在那裏更改狀態/道具。你會得到這樣的警告:'警告:setState(...):在現有狀態轉換期間無法更新[...]'。我真的很喜歡在'mergeProps'中做到這一點?你有沒有這個問題,並找到一個很好的解決方法? –

+1

忘掉我以前的評論。我剛纔已經看到你實際上有一個定義了觸發動作的函數。我假設你在你的組件中使用它,然後工作。應該仔細閱讀。謝謝你回答順便說一句。 :) –

0

分離「容器」和「演示組件」的主要好處之一是處理其中特定組件的所有邏輯。也就是說,你可以定義一個動作來改變你的狀態,只有在有效時纔會觸發它。

Class PresentationalComponent extends React.Component { 
    ... 
    onEventHandler() { 
    if (eventIsValid) this.props.changeState(); 
    } 
    ... 
} 

和:

Class ContainerComponent extends React.Component { 
    ... 
    render() { 
    <PresentationalComponent changeState={actions.changeState} /> 
    } 
}