简体   繁体   English

向React HOC产品注入新的内联样式

[英]Inject new inline styles to a React HOC product

Using a common HOC pattern like so works beautifully. 这样使用通用的HOC模式效果很好。 However, there are times when you really don't want a component to be wrapped and just want the same component you passed in extended a bit. 但是,有时您确实不希望包装组件,而只是想要扩展传入的相同组件。 That's what I'm struggling with here. 这就是我在这里苦苦挣扎的事情。

Wrapper HOC 包装HOC

const flexboxContainerStyles = {
  display: 'flex',
  flexDirection: 'row',
  backgroundColor: 'pink',
}

let WrapInFlexContainer = FlexChild => class extends React.Component {
  render(){

    return (
      <div className="flexContainer" style={flexboxContainerStyles} >
        <FlexChild {...this.props} />
      </div>
    )
  }
}

const Button = (props) => <button>{props.txt}</button>
let FlexButton = WrapInFlexContainer(Button);

The following examples result in a button with no style attributes. 以下示例导致一个没有样式属性的按钮。

Example 1.1: pass-through via createClass 例1.1:通过createClass传递

function hocPassThroughViaClass(Component) {
  return React.createClass({
    render: function() {
     return <Component {...this.props} style={flexboxContainerStyles}/>;
    }
  });
}

Example 1.2 pass-through via direct render 例1.2通过直接渲染传递

let hocPassThroughViaRender = Element => class extends React.Component {
  render(){   
    return <Element {...this.props} className="flexContainer" style={flexboxContainerStyles} />
  }
}

Example 2: create 示例2:创建

function hocCreate(Component) {
  return React.createClass({
    render: function() {
      const modifiedProps = Object.assign({}, {...this.props}, {...flexboxContainerStyles});
      return React.createElement(Component, { ...modifiedProps });
    }
  });
}

Example 3: clone 示例3:克隆

function hocClone(Component) {
  return React.createClass({
    render: function() {
      const modifiedProps = Object.assign({}, {...this.props}, {...flexboxContainerStyles});
      return React.cloneElement(<Component {...modifiedProps } />);
    }
  });
}

// render examples
let HOCPassThroughViaClassButton = hocPassThroughViaClass(Button); // 1.1
let HOCPassThroughRenderButton = hocPassThroughViaRender(Button); // 1.2 
let HOCCreatedButton = hocCreate(Button); // 2
let HOCClonedButton = hocClone(Button); // 3

From a couple of points I'm seeing here and there across the web, it doesn't seem like it's possible to return the same Component if it is an only child. 从我在网上各处所见到的几点来看,如果它是独生子,似乎不可能返回相同的Component

See: https://github.com/threepointone/glamor/blob/master/docs/createElement.md 参见: https : //github.com/threepointone/glamor/blob/master/docs/createElement.md

https://discuss.reactjs.org/t/trying-to-do-a-reactdom-render-a-el-replacing-the-el-not-appending-to-it/2681/2 https://discuss.reactjs.org/t/trying-to-do-a-reactdom-render-a-el-replacing-the-el-not-appending-to-it/2681/2

The following examples result in a button with no style attributes. 以下示例导致一个没有样式属性的按钮。

Isn't this happening because you're not passing the style prop along? 这是不是因为您没有传递样式道具而发生? Wouldn't this be fixed by doing this: 通过这样做不能解决此问题:

const Button = (props) => <button style={props.style}>{props.txt}</button>

Update: 更新:

HOCs don't magically apply props to children of the wrapped component, meaning that low level elements like <button /> or <div /> need props passed to them one way or another. HOC不会神奇地将props应用于包装组件的子元素,这意味着像<button /><div />这样的低级元素需要以一种或另一种方式传递给它们的prop。 You're passing props to <Button /> , not <button /> . 您正在将道具传递给<Button /> ,而不是<button /> You can however make an HOC that takes a basic element and adds whatever to it. 但是,您可以制作一个带有基本元素并为其添加任何内容的HOC。

let hoc = element => (
  class extends React.Component {
    render() {
      let { children, ...props } = this.props
      return React.createElement(
        element, 
        { ...props, style: flexboxContainerStyles },
        children,
      )
    }
  }
)

Usage: 用法:

let FlexButton = hoc('button')

let App = props => <FlexButton>{props.txt}</FlexButton>

fiddle 小提琴

That being said, you're not changing the API of the base component by passing along known props like style and className along. 话虽如此,您不会通过传递已知的道具(例如style和className)来更改基本组件的API。 In fact it's a great way to make components more reusable without specifying implementation details. 实际上,这是在指定实现细节的情况下使组件更可重用的好方法。

// good!
let Button = ({ children, ...props }) => <button {...props}>{children}</button>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM