如何在 React 上正确使用带有样式组件画布的 TypeScript 类型
Posted
技术标签:
【中文标题】如何在 React 上正确使用带有样式组件画布的 TypeScript 类型【英文标题】:How to properly use TypeScript types with a Styled Component canvas on React 【发布时间】:2020-09-19 03:41:13 【问题描述】:我正在使用 TypeScript 在 Gatsby 上创建一个 React 组件,并以这种方式定义了一个画布样式组件:
const Background = styled.canvas`
position: fixed;
width: 100%;
height: 100%;
`;
为了使用它,我以这种方式为其分配类型:
const canvas: htmlCanvasElement = Background,
context = Background.getContext('2d');
但我在画布类型中遇到此错误:
Type 'String & StyledComponentBase<"canvas", any, , never> & NonReactStatics<never, >' is missing the following properties from type 'HTMLCanvasElement': height, width, getContext, toBlob, and 238 more.
.getContext()
方法也出现错误:
This expression is not callable.
Type 'never' has no call signatures.
我一直在寻找解决方案,但找不到适合此特定问题的解决方案。 有人可以向我解释一下在 TypeScript 中使用 Styled Component 画布的最佳方式吗?
【问题讨论】:
This 可能有点相关。 谢谢@AjeetShah,我去看看! 【参考方案1】:Background
是 React.Component
(即创建虚拟元素的函数)而不是 HTMLCanvasElement
。不仅需要调用该函数,它甚至可以远程返回任何东西,例如HTMLCanvasElement
,而且您还需要访问底层 DOM 元素才能使其工作。不过,我确实有一个建议,您可以尝试一下。
import useRef, useEffect from 'react';
const Background = styled.canvas`
position: fixed;
width: 100%;
height: 100%;
`;
const ComponentUsingTheCanvas = () =>
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() =>
const context = canvasRef.current.getContext('2d');
// Do stuff with your canvas context here
);
return (
<Background ref=canvasRef />
);
请注意,我没有输入任何内容,因为 TypeScript 大部分时间都可以自动完成。
顺便说一句,既然可以内联样式,为什么还要使用样式化组件呢? styled-components
只有在你 do something with the props 时才真正有用。
【讨论】:
嗨,@101arrowz 谢谢你的回答,这让我明白了一些我不清楚的事情。我尝试了您的代码,但在使用有关它为空的上下文时出现错误。但我喜欢你添加内联样式的方法。我喜欢使用 styled-components,因为不仅使用道具,而且将我的组件重命名为更有意义的名称,最终使代码更清晰。您的方法帮助我找到了解决上下文中 null 问题的解决方案。【参考方案2】:@101arrowz 的答案几乎是正确的,但上下文有问题导致我出现此错误。
Object is possibly 'null'.
但它帮助我找到了一种内联样式的不同方法并以这种方式解决问题:
const Component: React.FC = () =>
const canvasRef = React.useRef<HTMLCanvasElement>(null);
const [context, setContext] = React.useState<CanvasRenderingContext2D | null>(
null
);
React.useEffect(() =>
if (canvasRef.current)
const renderCtx = canvasRef.current.getContext('2d');
if (renderCtx)
setContext(renderCtx);
, [context]);
return (
<div>
<canvas
id="canvas"
ref=canvasRef
style=
position: 'fixed',
width: '100%',
height: '100%'
></canvas>
</div>
);
【讨论】:
检查我更新的答案。我忘了在useRef
泛型中设置canvasRef
的类型。它现在应该可以工作了。当然,您的解决方案有效,但您将强制进行许多重新渲染。只需在 Component
的正文中尝试 console.log('hi')
即可了解我的意思。
另外,我的原始代码的唯一问题是 TypeScript 抱怨,但无论哪种方式在运行时都应该没有问题。以上是关于如何在 React 上正确使用带有样式组件画布的 TypeScript 类型的主要内容,如果未能解决你的问题,请参考以下文章
使用带有样式组件和主题的 react-test-renderer (React Native)
如何在带有 TypeScript 的 React-Native 中使用 styled-component 键入无状态功能组件?