像这样使用普通的 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
最佳答案
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>
话虽如此,您并没有通过传递样式和类名等已知属性来更改基础组件的 API。事实上,这是使组件更易于重用的好方法, 无需指定实现细节。
// good!
let Button = ({ children, ...props }) => <button {...props}>{children}</button>
关于javascript - 向 React HOC 产品注入(inject)新的内联样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40271866/