2016-06-13 45 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} /> 
    } 
}