javascript - 向 React HOC 产品注入(inject)新的内联样式

标签 javascript css reactjs

像这样使用普通的 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);

以下示例生成一个没有样式属性的按钮。

示例 1.1:通过 createClass 传递

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

示例 1.2 通过直接渲染传递

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

示例2:创建

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

示例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

从我在网络上到处看到的几点来看,如果它是独生子,似乎不可能返回相同的 Component

参见: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

最佳答案

The following examples result in a button with no style attributes.

发生这种情况不是因为您没有传递 style Prop 吗?这样做不会解决这个问题吗:

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

更新:

HOC 不会神奇地将 props 应用到包装组件的子组件,这意味着像 <button /> 这样的低级元素或 <div />需要以某种方式传递给他们的 Prop 。您正在将 Prop 传递给 <Button /> , 不是 <button /> .但是,您可以制作一个 HOC,它采用基本元素并向其添加任何内容。

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

用法:

let FlexButton = hoc('button')

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

fiddle

话虽如此,您并没有通过传递样式和类名等已知属性来更改基础组件的 API。事实上,这是使组件更易于重用的好方法, 无需指定实现细节。

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

关于javascript - 向 React HOC 产品注入(inject)新的内联样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40271866/

相关文章:

javascript - 在 JavaScript 中每 N 秒调用一次异步函数

css - 从样式表中获取颜色属性

html - 如何让表格占用剩余空间的100%?

javascript - React-router 更新 url 但组件未加载

ios - 推送新屏幕时 react 导航错误

javascript - 如何使用 JavaScript 在代码隐藏文件中查找动态创建的元素

javascript - 事件和 Action 是否有 1 :1 relationship in Redux?

javascript - 使用 Zurb Foundation 在顶部栏中使用 Postfix 按钮输入

javascript - 将文本放在 p5.js 中的草图之上

javascript - 如何在 React 中循环一个对象?