[英]No overload matches for this call, extra custom prop of styled component
No overload matches for this call此调用没有重载匹配
For props x, y in StyledContainer
, it's throwing "No overload matches for this call".对于StyledContainer
中的道具x, y ,它会抛出“此调用没有重载匹配项”。
import React from "react";
import styled, { css } from "styled-components";
interface Props {
onDragStart?: () => void;
onDragEnd?: () => void;
children: React.ReactNode;
isDragging: boolean;
x?: number;
y?: number;
onDrag?: (position: { translateX: number; translateY: number }) => void;
}
interface State {
originalX: number;
originalY: number;
lastTranslateX: number;
lastTranslateY: number;
translateX: number;
translateY: number;
isDragging: boolean;
}
export default class EventRecap extends React.Component<Props, State> {
state = {
isDragging: false,
originalX: 0,
originalY: 0,
translateX: 0,
translateY: 0,
lastTranslateX: 0,
lastTranslateY: 0,
};
componentWillUnmount() {
window.removeEventListener("mousemove", this.handleMouseMove);
window.removeEventListener("mouseup", this.handleMouseUp);
}
handleMouseDown = ({
clientX,
clientY,
}: {
clientX: number;
clientY: number;
}) => {
window.addEventListener("mousemove", this.handleMouseMove);
window.addEventListener("mouseup", this.handleMouseUp);
if (this.props.onDragStart) {
this.props.onDragStart();
}
this.setState({
originalX: clientX,
originalY: clientY,
isDragging: true,
});
};
handleMouseMove = ({
clientX,
clientY,
}: {
clientX: number;
clientY: number;
}) => {
const { isDragging } = this.state;
const { onDrag } = this.props;
if (!isDragging) {
return;
}
this.setState(
(prevState) => ({
translateX: clientX - prevState.originalX + prevState.lastTranslateX,
translateY: clientY - prevState.originalY + prevState.lastTranslateY,
}),
() => {
if (onDrag) {
onDrag({
translateX: this.state.translateX,
translateY: this.state.translateY,
});
}
},
);
};
handleMouseUp = () => {
window.removeEventListener("mousemove", this.handleMouseMove);
window.removeEventListener("mouseup", this.handleMouseUp);
this.setState(
{
originalX: 0,
originalY: 0,
lastTranslateX: this.state.translateX,
lastTranslateY: this.state.translateY,
isDragging: false,
},
() => {
if (this.props.onDragEnd) {
this.props.onDragEnd();
}
},
);
};
render() {
const { children } = this.props;
const { translateX, translateY, isDragging } = this.state;
return (
<StyledContainer
x={translateX}
y={translateY}
isDragging={isDragging}
onMouseDown={this.handleMouseDown}
>
{children}
</StyledContainer>
);
}
}
const StyledContainer = styled.div.attrs<Props>((props) => ({
style: { transform: `translate(${props.x}px, ${props.y}px)` },
}))`
cursor: grab;
${({ isDragging }: { isDragging: boolean }) =>
isDragging &&
css`
opacity: 0.8;
cursor: grabbing;
`};
`;
Instead of using attributes merging with styled.div.attrs<Props>
, directly use custom props so that they are exposed as the styled component props definition as well:不要使用与styled.div.attrs<Props>
合并的属性,而是直接使用自定义道具,以便它们也作为样式化组件道具定义公开:
// Add the custom Props as a TypeScript type argument to styled.div
// https://styled-components.com/docs/api#using-custom-props
const StyledContainer2 = styled.div<Props>`
cursor: grab;
/* Directly adapt style based on props, instead of merging attributes
https://styled-components.com/docs/basics#adapting-based-on-props */
transform: ${(props) => css`translate(${props.x}px, ${props.y}px)`};
${({
// No need to redefine type, it is directly taken from the custom props type argument of styled.div
isDragging
}) =>
isDragging
? css`
opacity: 0.8;
cursor: grabbing;
`
: ""};
`;
Then you can use these props directly inside the style block and adapt style based on props (instead of the attributes merging).然后你可以直接在样式块中使用这些道具并根据道具调整样式(而不是属性合并)。
Another advantage is that the props typing is directly available when you interpolate your function, so there is no need to redefine the props type.另一个优点是,当您插入 function 时,道具类型可以直接使用,因此无需重新定义道具类型。
Demo: https://codesandbox.io/s/laughing-rgb-oomc6n?file=/src/App.tsx:330-972演示: https://codesandbox.io/s/laughing-rgb-oomc6n?file=/src/App.tsx:330-972
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.