具有Canvas的可重用react组件不会使用其道具渲染画布

问题描述 投票:0回答:2

我正在尝试创建可重用的有状态组件(它不应是功能组件)。我需要在运行时添加此组件,因此在我的应用程序中,我处于状态的组件数组(CanvasComponent)呈现了组件列表。我还生成一个随机大小来渲染画布的大小。创建第二个画布时会发生问题,奇怪的是它仅渲染一次。我在ChartJS中遇到了这个问题,由于我的代码库很大,因此我决定通过一个示例来简化它。


但是,如果您取消注释数组中的CanvasComponent,它的工作就很好。

import React from 'react';
import logo from './logo.svg';
import './App.css';
import CanvasComponent from './CanvasComponent';

class App extends React.Component {

  state = {
    canvasList: [
      // <CanvasComponent size={30}></CanvasComponent>, 
      // <CanvasComponent size={50}></CanvasComponent>
    ]
  }


  handleClick = () => {

    const size = Math.floor(Math.random() * (100 - 50 + 1) + 50);
    const newCanvas = <CanvasComponent size={size}></CanvasComponent>

    this.setState({
      canvasList: [newCanvas, 
          ...this.state.canvasList]
  })

  }



  render() {
    return (
      <div className="App">
        <button onClick={this.handleClick}>Add canvas</button>

        { this.state.canvasList.map((item, i) => {
            return <CanvasComponent {...item.props} key={i}></CanvasComponent>
        })}

      </div>
    );
  }
}

export default App;

和组件

import React from 'react'

class CanvasComponent extends React.Component {
    constructor(props) {
      super(props);
      this.myCanvas = React.createRef();
    }

    componentDidMount() {
      const ctx = this.myCanvas.current.getContext('2d');
      ctx.fillRect(0, 0, 100, 100);
    }

    render() {
        console.log(this.props);
      return (
        <div>
            <p>Size should be {this.props.size}</p>
            <canvas ref={this.myCanvas} width={this.props.size} height={this.props.size} />
        </div>
      )
    }
}

export default CanvasComponent
reactjs chart.js react-component
2个回答
0
投票

我相信您在这里的问题是,您正在以编程方式呈现画布组件。如果首次加载页面时不存在某些内容,则事件侦听器不会主动寻找它。

我确信有比我的解决方案更好的解决方案,但我倾向于通过编写类似的方法来解决此问题。

state={ updated: false}


componentDidMount(){
this.setState({updated:true})
}

更新状态会强制重新渲染,事件侦听器将知道要注意相关组件。


0
投票

问题在这里,如果有人遇到同样的问题,我可以在这里分享。

代替

   this.setState({
      canvasList: [newCanvas, 
          ...this.state.canvasList]
   })

您应该写

   this.setState({
      canvasList: [...this.state.canvasList, 
         newCanvas]
   })

我仍然不知道为什么,但是它解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.