Reactjs 如何在React上正确使用带有样式化组件画布的TypeScript类型

Reactjs 如何在React上正确使用带有样式化组件画布的TypeScript类型,reactjs,typescript,canvas,gatsby,styled-components,Reactjs,Typescript,Canvas,Gatsby,Styled Components,我正在使用TypeScript在Gatsby上创建一个React组件,并以这种方式定义了一个画布样式的组件: const Background = styled.canvas` position: fixed; width: 100%; height: 100%; `; const canvas: HTMLCanvasElement = Background, context = Background.getContext('2d'); const Component: Re

我正在使用TypeScript在Gatsby上创建一个React组件,并以这种方式定义了一个画布样式的组件:

const Background = styled.canvas`
  position: fixed;
  width: 100%;
  height: 100%;
`;
const canvas: HTMLCanvasElement = Background,
  context = Background.getContext('2d');
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>
  );

为了使用它,我以这种方式为它分配类型:

const Background = styled.canvas`
  position: fixed;
  width: 100%;
  height: 100%;
`;
const canvas: HTMLCanvasElement = Background,
  context = Background.getContext('2d');
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>
  );

但我在canvas类型中遇到了以下错误:

我一直在寻找解决办法,但找不到适合这个具体问题的办法。
有人能给我解释一下将样式化组件画布与TypeScript一起使用的最佳方法吗?

背景
是一个
React.Component
(即创建虚拟元素的函数),而不是
HTMLCanvasElement
。不仅需要调用该函数才能远程返回任何东西,比如
htmlcanvaseElement
,还需要访问底层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} />
  );
}
从'react'导入{useRef,useffect};
const Background=styled.canvas`
位置:固定;
宽度:100%;
身高:100%;
`;
const ComponentUsingTheCanvas=()=>{
const canvasRef=useRef(null);
useffect(()=>{
const context=canvasRef.current.getContext('2d');
//在这里处理画布上下文
});
返回(
);
}
注意,我没有键入任何内容,因为TypeScript大部分时间都可以自动完成


顺便问一下,既然可以内联设置样式,为什么还要使用样式化组件呢<代码>样式化组件
只有在您需要时才真正有用。

来自@101arrowz的答案几乎是正确的,但在导致此错误的上下文中存在问题

但它帮助我找到了一种不同的方法,将样式内联并以这种方式解决问题:

const Background = styled.canvas`
  position: fixed;
  width: 100%;
  height: 100%;
`;
const canvas: HTMLCanvasElement = Background,
  context = Background.getContext('2d');
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>
  );

const组件:React.FC=()=>{
const canvasRef=React.useRef(null);
const[context,setContext]=React.useState(
无效的
);
React.useffect(()=>{
如果(canvasRef.current){
const renderCtx=canvasRef.current.getContext('2d');
如果(renderCtx){
setContext(renderCtx);
}
}
},[上下文];
返回(
);

可能有些关联。谢谢@AjeetShah,我会看一看!嗨,@101arrowz谢谢你的回答,它让我明白了一些我不清楚的事情。我尝试了你的代码,但在使用上下文时出错,因为它是空的。但我喜欢你的内联添加样式的方法。我喜欢使用样式化组件,因为不只是使用道具,而是将我的组件重命名为更有意义的名称,这最终会使代码更清晰。你的方法帮助我找到了解决上下文中空值问题的解决方案。检查我更新的答案。我忘记了在
useRef
泛型中设置
canvasRef
的类型。它应该是rk现在。当然,您的解决方案是有效的,但您将强制执行许多重新加载。只需尝试
组件
主体中的
console.log('hi')
,以了解我的意思。此外,我的原始代码的唯一问题是TypeScript抱怨,但在运行时应该没有任何问题。