以下是高阶组件。 HOC专门连接到redux以访问其中一个动作创建者:importantReduxAction
。
function withExtraStuff (InnerComponent) {
return class Enhancer extends React.Component {
constructor(props){
super(props)
this.importantMethod = this.importantMethod.bind(this)
}
importantMethod(){
//try to call the higher order component's action creator
this.props.importantReduxAction()
}
render(){
return <InnerComponent
{...this.props}
importantMethod={this.importantMethod}
/>
}
}
let mapDispatchToProps = (dispatch)=>{
return bindActionCreators({importantReduxAction}, dispatch)
}
return connect(null, mapDispatchToProps, null, {pure: false})(Enhancer)
}
这是将使用HOC组件的包装组件。它还将自身连接到redux,以便访问不同的方法:otherReduxAction
。
class ChildComponent extends React.Component {
constructor(props){
super(props)
this.doImportantThing = this.doImportantThing.bind(this)
}
doImportantThing(){
//try to call the higher order component's method (this is where problems occur)
this.props.importantMethod()
//do something with this components dispatch
this.props.otherReduxAction()
}
render(){
return <div>
{this.doImportantThing()}
</div>
}
}
let EnhancedComponent = withExtraStuff(ChildComponent)
let mapDispatchToProps = (dispatch)=>{
return bindActionCreators({otherReduxAction}, dispatch)
}
export default connect(null, mapDispatchToProps, null, {pure: false})(EnhancedComponent)
问题是我的HOC中的mapDispatchToProps
被孩子覆盖,而动作创建者:importantReduxAction
永远不会被传递到我的HOC中。它收到错误:
方法未定义
我已经通过将方法传递到我的子组件中解决了这个问题,如下所示:
/* CHILD COMPONENT DEFINITION ABOVE */
let mapDispatchToProps = (dispatch)=>{
return bindActionCreators({otherReduxAction, importantReduxAction}, dispatch)
}
但是那个解决方案并不是我希望事情发挥作用的方式。有没有办法让我的HOC合并到它想要与包装组件使用的动作创建器中?或者我是否必须找到一种新方法呢?
TLDR: HOC使用动作创建者的组件包装也具有动作创建者的子组件。 HOC行动创造者受到遏制并且永远不会过去。
答案 0 :(得分:2)
您的示例似乎有问题。
function withExtraStuff (InnerComponent) {
return class Enhancer extends React.Component {/* ... */}
// ...
return connect(/* ... */)(Enhancer)
}
您从HOC {{}} {{}}两次,因此return
永远不会Enhancer
。
这只是你的例子中的拼写错误吗?或者你的代码中有同样的问题吗?因为那确实会引起你所看到的问题。
答案 1 :(得分:0)
这里的问题是,您需要将道具合并到更高阶的组件中。 Redux连接采用第三个参数,它是一个函数(mergeProps)。此函数采用三个参数。在此处查看示例:
function mergeProps(stateProps, dispatchProps, ownProps) {
return {
...stateProps,
...dispatchProps,
...ownProps,
actions: Object.assign({}, dispatchProps.actions, ownProps.actions)
}
}
在包装组件中,我像这样设置mapDispatchToProps:
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
...myDefinedActionsForMyComponent,
}, dispatch)
}
}
在我的HOC中,我以相同的方式设置了mapDispatchToProps。您可以通过在HOC(高阶组件)中实现mergeProps来解决您遇到的问题。如果仅创建mergeProps函数并在控制台上记录这三个参数,您将看到这些值并可以决定如何最佳地将它们结合在一起。根据我的设置,我只需要对操作进行对象分配。您可能需要做类似的事情。
然后,连接在您的HOC中将如下所示:
return connect(mapStateToProps, mapDispatchToProps, mergeProps)(Wrapper)