如何在不将组件包装在<div>内的情况下进行悬停状态HOC?

时间:2019-01-26 15:15:41

标签: javascript reactjs higher-order-components

我试图编写一个高阶组件,该组件为组件提供悬停属性。但是我无法使其与任何类型的组件一起使用。

我的HOC

function withHover(WrappedComponent) {
  return class extends Component {
    state = {
      hover: false
    }
    onMouseEnter(){
      this.setState({hover: true});
    }
    onMouseLeave(){
      this.setState({hover: false});
    }
    render() {
      return (
        <div onMouseEnter={this.onMouseEnter.bind(this)} onMouseLeave={this.onMouseLeave.bind(this)}>
          <WrappedComponent {...this.props} hover={this.state.hover}/>
        </div>
      )
    }
  }
}

我的问题是我必须将组件包装在div中才能使OnMouse事件起作用。但是,例如,当我想在<tr>内使<table>处于可悬停状态时,<tr>将被包装到<div>中,这会破坏<table>的逻辑。 / p>

我曾考虑过将HOC的OnMouse事件处理程序传递给包装的组件并在其中进行调用,但这并不是很方便,因为所有这些目的都是为了节省开发时间

所以我的问题是:如何重写此HOC以避免将初始组件包装在<div>中?

感谢您的时间

2 个答案:

答案 0 :(得分:2)

您可以仅从HOC渲染WrappedComponent并将onMouseEnteronMouseLeave函数作为道具传递,然后由传播算子在道具上用于包装的组件中

代码如下:

function withHover(WrappedComponent) {
  return class extends Component {
    state = {
      hover: false
    }
    onMouseEnter = () => {
      this.setState({hover: true});
    }
    onMouseLeave = () => {
      this.setState({hover: false});
    }
    render() {
      return <WrappedComponent onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} {...this.props} hover={this.state.hover}/>
    }
  }
}

const TableRow = props => {
  return (
    <tr {...props}>
      {props.children}
    </tr>
  )
}
const TableRowWithHover = withHover(TableRow);

答案 1 :(得分:1)

将子组件包装在父组件中的片段中 将事件传递给子榆树
榆木

class Child extends Component {
  render() {
    return (
      <div
        onMouseLeave={this.props.onMouseLeave || null}
        onMouseEnter={this.props.onMouseEnter || null}
      >
        This is a child Component
      </div>
    );
  }
}

父组件(包装器)

import Child from './child';
class Parent extends Component {
    state = {  }
    onMouseEnter = () =>{
        console.log("mosuse Entered child")
    }
    onMouseLeave = () =>{
        console.log("mosuse left child")
    }
    render() { 
        return ( 
            <>
            <Child onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}></Child>
            </>
         );
    }
}