想象一下我正在编写一个React应用,用户可以在其中向不同的“工作区”添加不同颜色和尺寸的形状。假设我们有Circle
和Square
组件,它们将具有不同的属性来定义它们。当用户添加形状时,其道具将添加到工作区组件的状态。然后,工作区将绘制如下形状:
import React, {useState} from "react";
interface ISquareProps {
color: string;
lineLength: number;
}
interface ICircleProps {
color: string;
radius: number;
}
const Square = ({lineLength}: ISquareProps) => (<div>I'm a square with line length {lineLength}</div>);
const Circle = ({radius}: ICircleProps) => (<div>I'm a circle with radius {radius}</div>);
const Workspace = () => {
const [squares, setSquares] = useState(new Array<ISquareProps>());
const [circles, setCircles] = useState(new Array<ICircleProps>());
return (
<>
{squares.map((square) => <Square {...square} /> )}
{circles.map((circle) => <Circle {...circle} /> )}
</>
);
};
在此处查找示例:
虽然这对于两种不同的形状都适用,但如果我们有很多形状,就会变得很麻烦。
如果形状知道如何渲染自己该怎么办?那呢:
import React, {useState} from "react";
interface IShapeProps {
color: string;
render(): JSX.Element;
}
// ------- square -------
interface ISquareProps extends IShapeProps {
lineLength: number;
}
const Square = ({lineLength}: ISquareProps) => (<div>I'm a square with line length {lineLength}</div>);
class SquareProps implements ISquareProps {
public color: string;
public lineLength: number;
constructor(lineLength: number, color: string) {
this.color = color;
this.lineLength = lineLength;
}
public render() {
return <Square {...this} />;
}
}
// ------- circle -------
interface ICircleProps extends IShapeProps {
radius: number;
}
const Circle = ({radius}: ICircleProps) => (<div>I'm a circle with radius {radius}</div>);
class CircleProps implements ICircleProps {
public color: string;
public radius: number;
constructor(color: string, radius: number) {
this.color = color;
this.radius = radius;
}
public render() {
return <Circle {...this} />;
}
}
// ------- workspace -------
const Workspace = () => {
const [shapes, setShapes] = useState(new Array<IShapeProps>());
return (
<>
{shapes.map((shape) => shape.render() )}
</>
);
};
一个工作示例在这里:
这是处理带有功能组件的“多态”组件的可行方法吗? 是否应该考虑替代模式?
答案 0 :(得分:0)
您似乎正在做的只是使用Shape
和Circle
组件,但是据我所知,您的render方法实际上并不能告诉形状是什么形状。
您需要对该渲染函数进行参数设置,以决定它是哪个。
您可以进行一些改进:
1)虽然对我来说更有意义,而不是仅仅使用一些“功能”来简化它,而是将其包装在足够明智的react组件中。
2)使用道具代替类属性,这就是它们的目的。没有理由将其重新分配给this
变量
3)使用条件JSX根据道具决定要渲染的组件(您甚至可以切换形状,并且它们会随着新道具触发重新渲染而切换)
4)我认为不需要单独实现您拥有的prop接口,可以与功能组件内联实现
export const Shape = (props: IShapeProps) => {
public render() {
if (this.props.shapeType === 'Square') {
return <Square lineheight={this.props.lineheight} color={this.props.color} />;
} else {
return <Circle radius={this.props.radius} color={this.props.color} />;
}
}
}