使用像这样的普通HOC模式可以很好地工作。但是,有时候你真的不想要一个组件被包装,只是希望你传入的相同组件有点扩展。这就是我在这里挣扎的事情。
Wrapper 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
答案 0 :(得分:1)
以下示例生成一个没有样式属性的按钮。
这不是因为你没有通过风格道具吗?这样做不会解决这个问题:
const Button = (props) => <button style={props.style}>{props.txt}</button>
更新
HOC不会神奇地将道具应用于包裹组件的子项,这意味着像<button />
或<div />
这样的低级元素需要以这种或那种方式传递给它们的道具。您将道具传递给<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 强>
话虽这么说,你并没有通过传递类似style和className的已知道具来改变基本组件的API。实际上,这是使组件更具可重用性的好方法,而无需指定实现细节。
// good!
let Button = ({ children, ...props }) => <button {...props}>{children}</button>