是否可以为 React 组件实现类似继承的机制以减少几乎重复的代码?
Is it possible to implement an inheritance like mechanism for React components in order to reduce nearly duplicate code?
我发现我不得不重新实现很多相同的功能。例如,对于接下来的 3 个组件,我正在为 style
、className
和 id
实现相同的代码。我知道我可以将 {...props}
作为参数而不是听到,然后将 {...props}
传递给 return 函数内的容器,但如果我想要这些组件,我将无法执行此操作每个人都有自己的类名和样式,这些类名和样式总是分配给这些 类 的每个实例。我稍微研究了一下 higher-order-components,但无法理解在这种情况下我将如何使用它们
const styles = {
container:{
position: 'absolute'
},
}
const Modal = ({className, style, id, hidden, children}) => {
return (
<div
className={`modal ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
{!hidden && <ExtraContent />}
{children}
</div>
)
}
const styles = {
container:{
margin: 10
}
}
const VoteButton = ({className, style, id, pressed}) => {
let img
if (pressed){
img = './img_pressed.jpg'
}else{
img = './img_not_pressed.jpg'
}
return (
<div
className={`voteButton ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
<img src={img}>
</div>
)
}
const styles = {
container:{
display: 'flex'
}
}
const Navbar = ({className, style, id, links, children, ...props}) => {
return (
<nav
{...props}
className={`navbar ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
{links.map(lk => <a href={lk.href}>{lk.text}</a>
{children}
</nav>
)
}
明确地说,我正在寻找一种方法来避免必须为每个组件定义和修改 className
、style
和 id
。如果我能这样做一次就好了。我知道这对于第三个组件来说可能特别困难,因为它是 nav
而不是 div。
一种方法是使用 returns 您的组件函数:
function createComponentClass(Ele, name, styles, children) {
return (props) => {
const { className, style, id } = props;
return (
<Ele className={`${name} ${className}`} style={...{styles.container}, ...{style}} id={id}>
{children(props)}
</Ele>
);
};
}
const Modal = createComponentClass('div', 'modal', { container: { ... } }, (props) => {
return (
<>
{!props.hidden && <ExtraContent />}
{props.children}
</>
);
});
const VoteButton = createComponentClass('div', 'voteButton', { container: { ... } }, (props) => {
let img = pressed ? './img_pressed.jpg' : './img_not_pressed.jpg';
return <img src={img} />;
});
const Navbar = createComponentClass('nav', 'navbar', { container: { ... } }, (props) => {
return (
<>
{links.map(lk => <a href={lk.href}>{lk.text}</a>
{children}
</>
);
});
我发现我不得不重新实现很多相同的功能。例如,对于接下来的 3 个组件,我正在为 style
、className
和 id
实现相同的代码。我知道我可以将 {...props}
作为参数而不是听到,然后将 {...props}
传递给 return 函数内的容器,但如果我想要这些组件,我将无法执行此操作每个人都有自己的类名和样式,这些类名和样式总是分配给这些 类 的每个实例。我稍微研究了一下 higher-order-components,但无法理解在这种情况下我将如何使用它们
const styles = {
container:{
position: 'absolute'
},
}
const Modal = ({className, style, id, hidden, children}) => {
return (
<div
className={`modal ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
{!hidden && <ExtraContent />}
{children}
</div>
)
}
const styles = {
container:{
margin: 10
}
}
const VoteButton = ({className, style, id, pressed}) => {
let img
if (pressed){
img = './img_pressed.jpg'
}else{
img = './img_not_pressed.jpg'
}
return (
<div
className={`voteButton ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
<img src={img}>
</div>
)
}
const styles = {
container:{
display: 'flex'
}
}
const Navbar = ({className, style, id, links, children, ...props}) => {
return (
<nav
{...props}
className={`navbar ${className}`}
style={...{styles.container}, ...{style}}
id={id}
>
{links.map(lk => <a href={lk.href}>{lk.text}</a>
{children}
</nav>
)
}
明确地说,我正在寻找一种方法来避免必须为每个组件定义和修改 className
、style
和 id
。如果我能这样做一次就好了。我知道这对于第三个组件来说可能特别困难,因为它是 nav
而不是 div。
一种方法是使用 returns 您的组件函数:
function createComponentClass(Ele, name, styles, children) {
return (props) => {
const { className, style, id } = props;
return (
<Ele className={`${name} ${className}`} style={...{styles.container}, ...{style}} id={id}>
{children(props)}
</Ele>
);
};
}
const Modal = createComponentClass('div', 'modal', { container: { ... } }, (props) => {
return (
<>
{!props.hidden && <ExtraContent />}
{props.children}
</>
);
});
const VoteButton = createComponentClass('div', 'voteButton', { container: { ... } }, (props) => {
let img = pressed ? './img_pressed.jpg' : './img_not_pressed.jpg';
return <img src={img} />;
});
const Navbar = createComponentClass('nav', 'navbar', { container: { ... } }, (props) => {
return (
<>
{links.map(lk => <a href={lk.href}>{lk.text}</a>
{children}
</>
);
});