【问题标题】:Re-render Canvas in React Js在 React Js 中重新渲染画布
【发布时间】:2021-01-29 00:51:46
【问题描述】:

我有一个包含 500 行 X 500 列的网格数据的画布。我正在尝试更新 React 状态中的几个特定单元格,一旦更新反应状态,整个画布就会重新创建和渲染。有没有更好的方法来更新画布的一部分?下面是组件的流程

  1. componentDidMount() 中调用API 并将响应保存在状态中。
  2. 使用状态创建画布并在 UI 中呈现
  3. 30秒调用api并获取数据,只更新数据和更新状态。
  4. 目前,一旦状态更新,就会创建并渲染整个罐子
  5. 现在我可以只更新画布中最新更新的状态值吗?

【问题讨论】:

  • Reactjs 的全部意义在于不必重新渲染所有内容。为了回答您的问题,我们确实需要查看您的代码。
  • @jaesle 是的,我理解使用 react 并不是要重新渲染每一件事。我的用例是显示 500X500 个对象(大约 2,50,000 个对象)。为此,我创建并渲染了一个画布。现在,我想知道是否有办法只更新画布中所需的部分,而不是重新创建它
  • 你试过了吗?

标签: javascript reactjs user-interface canvas


【解决方案1】:

我认为画布中的项目数量不是问题。我猜问题是您需要以正确的方式更新项目。这是一个使用 Hooks 的示例,说明如何仅更新正在更改的画布部分而不更改所有内容。显然,它需要适应您的具体实例,但它应该为您提供如何做到这一点的方向。

function Canvas(props) {
  var item = 0;
  // pos is the item in the table that's going to be updated
  const [pos, setPos] = React.useState(0);
  //sample data
  const [A,setA] = React.useState([
    {data:"N", id:1},{data:"N",id :2},{data:"N",id :3},{data:"N",id :4}
   ]); 
  const totalitems = A.length;
  
  const canvasRef = React.useRef(null)
  
  function HandleClick() {
    let newArray = [...A];
    item=Math.floor(Math.random()*totalitems);
    // toggle between letters
    newArray[item].data == "N" ? newArray[item].data = "H" : newArray[item].data = "N" ; 
    setA(newArray); // set the entry in the array to the new letter
    setPos(item);
  };
    
  const tabledraw = ctx => {
    // The following line clears the whole canvas
    // ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)

    ctx.fillStyle = '#000000';
    // Clear only part of the canvas that corresponds to the size
    // of the text that is being replaced
    ctx.clearRect(pos*50, 0,50, 100);
    ctx.font = "30px Arial";
    // translate the position of the start of the canvas to where the 
    // character that is changing is
    ctx.translate(pos*50,0);
    ctx.fillText(A[pos].data, 0, 80);
    // Translate the canvas back to its original position
    ctx.translate(-pos*50,0);
    }
  
React.useEffect(() => {
    const canvas = canvasRef.current
    const context = canvas.getContext('2d')
    tabledraw(context)
    }, [tabledraw])
  
  return(
   <>
   <canvas ref={canvasRef} {...props}/>
   <button onClick={HandleClick}>Change</button>
   </>
  )
}

【讨论】:

  • 我面临的问题是没有更新组件状态。我在这里面临的主要问题是重新渲染或重新创建画布
  • 您能否分享您的代码或举例说明您遇到的问题,以便我们更好地帮助您?
  • 代码已更新以显示如何渲染画布的一部分而不是整个东西
猜你喜欢
  • 2021-12-29
  • 2013-02-18
  • 2016-01-11
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2015-06-30
相关资源
最近更新 更多