从HOC访问包装组件功能

时间:2017-04-18 11:33:43

标签: javascript reactjs

想象一下用于触摸行为的HOC,它通过onTouchStart检测关键触摸事件。现在使用touch HOC的包装组件将拥有自己的处理程序逻辑。我的HOC组件如何调用包装组件处理函数?

只是为了得到一个想法,这就是我需要的东西。在研究中,我发现this使用ref来调用目标组件。我想知道是否有更好的方法来实现这一目标。

TouchBehavior HOC

const TouchBehavior = (WrappedComponent) =>

    class extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                active: false,
            };
            this.handleAction = this.handleAction.bind(this);
            this.setActiveState = this.setActiveState.bind(this);
            this.resetActiveState = this.resetActiveState.bind(this);
        }

        handleAction(e) {
            e.preventDefault();
            this.setActiveState();
            //call wrapped component specific handler logic here
            _.delay(() => this.resetActiveState() , 150);
        }

        setActiveState() {
            this.setState ({
                active: true
            });
        }

        resetActiveState() {
            this.setState ({
                active: false
            });
        }

        render() {
            let touchBehaviorProps = {
                onTouchStart: this.handleAction
            };
            return <WrappedComponent {...this.props} touchBehaviorProps={touchBehaviorProps} />
        }
    };

已包装的组件

class Button extends React.Component {

 componentSpecificHandlerLogic(){
  //logic goes here
 }

 render () {
  return <button {..this.props.touchBehaviorProps}></button>
 }
}

1 个答案:

答案 0 :(得分:3)

只要有可能,我会尽量不将逻辑拉回到树上,而是向下传递更多。

可能有很多方法可以实现这一点,但我在这种情况下看到的一个选项是将提供给包装组件的prop更改为使用提供的自定义逻辑为它们构造处理程序的函数。

TouchBehavior HOC

const TouchBehavior = (WrappedComponent) =>

    class extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                active: false,
            };
            this.handleAction = this.handleAction.bind(this);
            this.setActiveState = this.setActiveState.bind(this);
            this.resetActiveState = this.resetActiveState.bind(this);
        }

        handleAction(e, customHandler) {
            e.preventDefault();
            this.setActiveState();
            customHandler();
            _.delay(() => this.resetActiveState() , 150);
        }

        setActiveState() {
            this.setState ({
                active: true
            });
        }

        resetActiveState() {
            this.setState ({
                active: false
            });
        }

        render() {
            let touchBehaviorProps = (customHandler) => ({
                onTouchStart: (e) => this.handleAction(e, customHandler)
            });
            return <WrappedComponent {...this.props} touchBehaviorProps={touchBehaviorProps} />
        }
    };

已包装的组件

class Button extends React.Component {

 componentSpecificHandlerLogic(){
  //logic goes here
 }

 render () {
  return <button {...this.props.touchBehaviorProps(componentSpecificHandlerLogic)}></button>
 }
}