react render-props vs 高階元件(HOC)
阿新 • • 發佈:2021-07-10
1. 建立方式
// render props class Mouse extends Component { state = { x: 0, y: 0 } handleMouseMove = e => { this.setState({ x: e.clientX, y: e.clientY, }) } componentDidMount() { window.addEventListener("mousemove", this.handleMouseMove) } componentWillUnmount() { window.removeEventListener("mousemove", this.handleMouseMove) } render() { const { flag, render, children } = this.props; return flag ? render(this.state) : children(this.state); } }
// HOC function withMouse(WrappedComponent) {class Mouse extends Component { state = { x: 0, y: 0 } handleMouseMove = e => { this.setState({ x: e.clientX, y: e.clientY, }) } componentDidMount() { window.addEventListener("mousemove", this.handleMouseMove) } componentWillUnmount() { window.removeEventListener("mousemove", this.handleMouseMove) } render() { return <WrappedComponent {...this.state} {...this.props}></WrappedComponent> } } Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}` return Mouse } function getDisplayName(WrappedComponent) { return WrappedComponent["displayName"] || WrappedComponent["name"] || "Component" }
2. 使用方式
// render props <Mouse flag={true} render={ mouse => { return ( <div> X: {mouse.x}, Y: {mouse.y} </div> ) } }></Mouse> <Mouse> { mouse => { return ( <div style={{ position: 'absolute', top: mouse.y - 50, left: mouse.x - 50, width: '100px', height: '100px', background: 'red' }}> </div> ) } } </Mouse>
// HOC const Position = props => ( <div> X:{props.x}, Y:{props.y} </div> ) const Cart = props => ( <div style={{ position: 'absolute', top: props.y - 50, left: props.x - 50, width: '100px', height: '100px', background: 'red' }}></div> ) const MousePosition = withMouse(Position); const MouseCart = withMouse(Cart);