尝试将React功能组件转换为类组件失败

时间:2020-10-09 03:14:59

标签: reactjs html5-canvas react-hooks

我正在尝试在this tutorial之后使用 React 来实现canvas,但是我不喜欢在具有状态或生命周期管理的情况下使用功能组件(我觉得这就是类的目的),所以我试图将教程功能组件转换为基于类的组件,这是我随附的代码:

import React from 'react';

class AppCanvas extends React.Component {
  constructor (props) {
    super(props);

    this.canvasRef = React.createRef();
    this.canvas = null;
    this.context = null;
  }

  draw = ctx => {
    ctx.fillStyle = '#00ff66'
    ctx.beginPath()
    ctx.arc(50, 100, 20, 0, 2*Math.PI)
    ctx.fill()
  }

  componentDidMount () {
    this.canvas = this.canvasRef.current;
    this.context = this.canvas.getContext('2d');
    this.context.fillStyle = '#000000';
    this.context.fillRect(0, 0, this.context.canvas.width, this.context.canvas.height);
  }

  render () {
    this.draw(this.context)

    return (
      <canvas className={this.props.classes.canvas} ref={this.canvasRef} />
    )
  }
}

export default AppCanvas;

但是我收到以下错误消息:

×
TypeError: Cannot add property fillStyle, object is not extensible
AppCanvas.draw
src/AppCanvas.js:13
  10 | }
  11 | 
  12 | draw = ctx => {
> 13 |   ctx.fillStyle = '#00ff66'
     | ^  14 |   ctx.beginPath()
  15 |   ctx.arc(50, 100, 20, 0, 2*Math.PI)
  16 |   ctx.fill()

我不知道我在做什么错。

1 个答案:

答案 0 :(得分:2)

componentDidMount()在render()之后被调用,在初始render()期间this.context为null,仅在componentDidMount()内部被初始化。

在componentDidMount中移动this.draw(this.context)之后,代码应如下所示。

import React from 'react';


class AppCanvas extends React.Component {
  constructor (props) {
    super(props);
    this.canvasRef = React.createRef();
    this.canvas = null;
    this.context = null;
  }

  draw = ctx => {
    ctx.fillStyle = '#00ff66'
    ctx.beginPath()
    ctx.arc(50, 100, 20, 0, 2*Math.PI)
    ctx.fill()
  }

  componentDidMount () {
    this.canvas = this.canvasRef.current;
    this.context = this.canvas.getContext('2d');
    this.draw(this.context)
    this.context.fillStyle = '#000000';
    this.context.fillRect(0, 0, this.context.canvas.width, this.context.canvas.height);
    this.draw(this.context)
  }

  render () {
    return (
      <canvas className={this.props.classes.canvas} ref={this.canvasRef} />
    )
  }
}

App Output